【问题标题】:Dynamically Building a List of Func<t,t> - then applying to a linq query动态构建 Func<t,t> 列表 - 然后应用于 linq 查询
【发布时间】:2011-11-07 15:16:29
【问题描述】:

不确定这是否是最好的方法,但这是我的想法

我正在使用实体框架数据模型 v 4.1 - 我正在尝试动态构建 where 语句,这样我就不必每次都查询数据库,而是可以构建一个“条件列表”,然后将它们全部应用到一次,所以数据库只被查询一次,而不是每次我添加我的新条件时——如果这有意义的话......

这就是我所拥有的

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();

我不确定我是否在这里采取了正确的方法 - 希望这是有道理的 - 任何指导,示例代码都会很棒,我花了很多时间在网上寻找示例/教程

【问题讨论】:

    标签: c# asp.net linq entity-framework-4 delegates


    【解决方案1】:

    你可以通过多次调用Where来做到这一点:

    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();
    

    在您开始尝试检索结果之前,它不会联系数据库。

    如果您真的想要创建一个列表,则需要创建一个List&lt;Expression&lt;Func&lt;Order, bool&gt;&gt;&gt; - 它们必须是表达式树而不是委托,以便实体框架可以处理它们。然后你可以这样做:

    foreach (var predicate in predicates)
    {
        query = query.Where(predicate);
    }
    

    或者您可以使用PredicateBuilder 构建单个表达式树。

    【讨论】:

    • 这个问题(据我了解)是每个查询都会针对数据库执行,我宁愿建立我的 where 语句,然后只执行 1 个数据库查询
    • @user630270:您的理解有缺陷 :) 正如我在回答中所写:“在您开始尝试检索结果之前,它不会联系数据库。”
    • 问题,所以只要我使用 IQueryable 它就不会执行,直到我真正开始访问属性等?这是 IQueryable 的功能之一吗?另外,是否会在这一行进行 db 查询: IQueryable query = Entities.Orders; ?或者仅在访问属性时-再次感谢
    • @user630270:不仅仅是 IQueryable - LINQ to Objects 也是如此。不,Entities.Orders 不会对数据库进行查询 - 它会有效地构建一个查询。
    • 当您开始访问结果时,将评估表达式(并执行查询),例如通过迭代、访问第一个元素或调用例如.ToList
    【解决方案2】:

    乔恩 - 当然 - 给出了如何更好地做到这一点的答案。

    但是对于您的原始观点,以及为什么这不起作用:

    应用孔列表并不难(只要做

    x => orderFunctions.All(f => f(x))
    

    ) 但你不会从中得到任何 SQL 的喜爱——这意味着你会得到一个错误,因为 EF 不知道如何处理所有内容(或者你将在那里编码的任何内容)。 您必须查询所有条目(使用 ToList 或 ToArray),然后它可以工作......但没有性能;)

    【讨论】:

    • ... 更好地使用 Jons 的答案 ;) (也许给演示一些支持?:D)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多