Dynamically Building a List of Func<t,t> - then applying to a linq query
Not sure if this is the best approach, however here are my thoughts
I am using Entity Framework Data Model v 4.1 - i'm trying to build a where statement dynamically so that I dont have to query the db everytime, instead i can build a "list of" conditionals, then apply them all at once so the db is only queryed once as opposed to everytime i add my new conditional - if that makes sense...
here is what i have
List<Func<Order, bool>> orderFunctions = new List<Func<Order, bool>>();
if (this.LoggedInUser.UserId == 9)
{
Func<Order, bool> deleg = o => o.Status.Equals(OrderStatus.NewOrder);
orderFunctions.Add(deleg);
}
else if (this.LoggedInUser.UserId == 22)
{
Func<Order, bool> deleg = o => o.AssignedToUserId.Equals(22);
orderFunctions.Add(deleg);
}
List<Orders> orders = Entities.Orders.Where( Some How Apply my Order Functions List Here ).ToList();
I'm not sure if i'm even taking the开发者_开发知识库 right approach here - hopefully this makes sense - any guidance, sample code would be fantastic, i've having a heck of a time finding examples / tutorials for this online
You can do this just by calling Where
multiple times:
IQueryable<Order> query = Entities.Orders;
if (this.LoggedInUser.UserId == 9)
{
query = query.Where(o => o.Status.Equals(OrderStatus.NewOrder));
}
else if (this.LoggedInUser.UserId == 22)
{
query = query.Where(o => o.AssignedToUserId.Equals(22));
}
List<Order> orders = query.ToList();
Until you start trying to retrieve the results, it won't contact the database.
If you really want to create a list, you'd need to create a List<Expression<Func<Order, bool>>>
- they have to be expression trees rather than delegates, so that the Entity Framework can deal with them. Then you could just do:
foreach (var predicate in predicates)
{
query = query.Where(predicate);
}
Or you could use PredicateBuilder
to build up a single expression tree.
Jon gave - of course - the answer how to do this better.
But for your original point, and why this won't work:
It is not dificult to apply the hole list (just do
x => orderFunctions.All(f => f(x))
) but you will not get any SQL-love from this - meaning you will get an error because EF cannot know what to do with the all (or whatever you will code there). You would have to query all entries (with ToList, or ToArray) and after this it would work ... but without performance ;)
精彩评论