In current ef core api state we can create query as described below:
DbContext.Foos.Where(f => f.Name == "bar").Where(f => f.Age > 10).ToList();
This is great, simple and work very well. The result query will be something like:
select * from Foo where name = 'bar' and age > 10
But, there's no way to concat predicate's with 'or' instead of 'and' with Where method, where the result query will be concatenated with 'or' instead of 'and'. So, i'm proposing a extension method that concat predicate/expressions with 'or'.
Ex:
DbContext.Foos.Where(f => f.Name == "bar").OrWhere(f => f.Age > 10).ToList();
The expression above will be translated to the following sql:
select * from Foo where name = 'bar' or age > 10
So, what you guys think about it ?
@CronosTs why not use .Where(f => f.Name == "bar" || f.Age > 10)
?
PredicateBuilder already does this.
@tuespetre is not possible to broke big queries in extensions methods since the '||' operator can only live inside the expression it self.
@bmarder Yes it does, but it is a third party library. And, it come with a side efect: i need to learn a new lib just to concat "Or" outside expressions. And, of course, i think that the efort to add this features is kid of low i gues (not sure, to be honest).
@CronosTs I take it you need to dynamically construct the predicate then. Have you considered using .NET Framework's Expression
API to accomplish this? Something like this:
using static System.Linq.Expressions.Expression;
ParameterExpression arg = Parameter(typeof(Foo));
Expression predicate = Equal(Property(arg, nameof(Foo.Name)), Constant("bar"));
if (someCheck)
{
predicate = Or(predicate, GreaterThan(Property(arg, nameof(Foo.Age)), Constant(10)));
}
query = query.Where(Lambda(predicate, arg));
@tuespetre I don't want to create everything dynamically. I just want to break my queries into little expressions that will be concatenated using 'or' instead of 'and'. I probably can create a Extension that does exacly this, but why such simple and usefull thing is not part of the kit of ef core ? I mean, do you really think that your solution is better than an 'OrWhere' extension method ?
And this is not a new request when comes to 'Entity Framework', or am i wrong ?
@CronosTs to be fair, the Enumerable
and Queryable
extensions belong to the .NET Framework (https://github.com/dotnet/corefx) rather than EF Core. You could always request the feature there, but I can think of a few reasons why it wouldn't go over well. OrWhere
would need to operate on some derived interface of IQueryable
, similar to how ThenOrderBy
/ThenOrderByDescending
operate on IOrderedQueryable
. This would require changing Where
to return something like IFilteredQueryable
or some such (a breaking change), and its sole purpose would be combining filters with &&
/II
, (something that can already be done with Expression
s.) Another thing is that all of the existing LINQ query operators are... well, actual query operators. They all return new nodes that represent the actual structure of a query's operations. OrWhere
would instead be dealing with the 'stuff' that goes inside one of those nodes, so OrWhere
would have to either break this pattern by returning a Where
node that combines the previous expression with the new one, or cause every single existing query provider out there, including old ones still used in production like LINQ-to-SQL, to have to implement support for the new operator, or throw errors when the new (seemingly primitive, 'should-just work'), extension is encountered. That's a lot of trouble to facilitate what seems to be an aesthetic preference and not a functional requirement. :frog: :tea:
Yep, what @tuespetre said. Thanks Derek! 馃槃
What if I want add an conditional Or?
.Where(f => f.Name == "bar" || f.Age > 10) // only add || f.Age when ageFilter is true ..
@tuespetre is not possible to broke big queries in extensions methods since the '||' operator can only live inside the expression it self.
@bmarder Yes it does, but it is a third party library. And, it come with a side efect: i need to learn a new lib just to concat "Or" outside expressions. And, of course, i think that the efort to add this features is kid of low i gues (not sure, to be honest).
Thanks finally someone of sense. Using a third party library just for that is not serious at all..
Most helpful comment
@CronosTs to be fair, the
Enumerable
andQueryable
extensions belong to the .NET Framework (https://github.com/dotnet/corefx) rather than EF Core. You could always request the feature there, but I can think of a few reasons why it wouldn't go over well.OrWhere
would need to operate on some derived interface ofIQueryable
, similar to howThenOrderBy
/ThenOrderByDescending
operate onIOrderedQueryable
. This would require changingWhere
to return something likeIFilteredQueryable
or some such (a breaking change), and its sole purpose would be combining filters with&&
/II
, (something that can already be done withExpression
s.) Another thing is that all of the existing LINQ query operators are... well, actual query operators. They all return new nodes that represent the actual structure of a query's operations.OrWhere
would instead be dealing with the 'stuff' that goes inside one of those nodes, soOrWhere
would have to either break this pattern by returning aWhere
node that combines the previous expression with the new one, or cause every single existing query provider out there, including old ones still used in production like LINQ-to-SQL, to have to implement support for the new operator, or throw errors when the new (seemingly primitive, 'should-just work'), extension is encountered. That's a lot of trouble to facilitate what seems to be an aesthetic preference and not a functional requirement. :frog: :tea: