【问题标题】:Dynamic predicate building in EF5EF5 中的动态谓词构建
【发布时间】:2013-02-15 20:28:40
【问题描述】:

好的,

我必须构建一个谓词以从 EF5 中的已知实体中选择未知数量的列 AND 按未知数量的列过滤 ONE 其中始终是来自子集合的名称。

这就是我最终需要的结果

var q = db.Set<Entity>()
          .Where(e => e.Code.Contains("q") || e.Translations.FirstOrDefault(t => t.Culture.ID == "whatever").Description.Contains("q"))
          .Select(e => new
                       {
                           e.ID,
                           e.Code,
                           Name = e.Translations.FirstOrDefault(t => t.Culture.ID == "whatever").Description
                       });

但我不确定如何为表达式构建谓词

e.Translations.FirstOrDefault(t => t.Culture.ID == "whatever").Description.Contains("q")

要选择的列和要过滤的字段以字符串数组的形式提供,在这种情况下,过滤器总是包含。

我熟悉构建谓词,这不是问题,更重要的是我以前从未研究过子集合,而且我现在处于完全“WTF”的状态:-)

任何和所有朝着正确方向的推动都将是最受重视的。

【问题讨论】:

    标签: linq-to-entities entity-framework-5 predicatebuilder


    【解决方案1】:

    一种方法可能是使用 DynamicLinq。见http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

    如果您向下查看第三个查询,您应该能够执行以下操作:

     e.Translations
    .Where("Culture.ID = 'whatever'") //Conditions defined as string as per example
    .FirstOrDefault() //etc.
    

    关于select an unknown number of columns from a known entity in EF5 AND filter by an unknown number of columns,您可以在使用之前使用构建字符串所需的任何表达式。对于“包含”子句,它有点复杂 - 请参阅此处描述的方法 - How to write String.Contains in Dynamic Linq

    我没有实际测试过这个,因为我无法访问 EF5,但看起来 DynamicLinq 有基于 EF5 的问题(所以它应该可以工作)-https://stackoverflow.com/questions/9929396/entity-framework-5-0-performance-with-dyanmic-linq

    另外,我应该指出,我更愿意为此目的使用 PredicateBuilder,但我相信如果不提前知道字段名/使用某种反射(参见 Using Dynamic Column Names in a Linq Query),您将无法做到这一点。同样值得承认的是这个答案 (https://stackoverflow.com/a/2497335/201648),它建议了上述方法。

    此外,可以使用 lambdas 为字段设置条件规则,如下所述:http://www.codeproject.com/Articles/28580/LINQ-and-Dynamic-Predicate-Construction-at-Runtime

    // use tryparse to make sure we don't run a bogus query.
    if (cbxUseEmployeeID.Checked &&
        int.TryParse(filterEmployeeId.Text, out emplId) &&
        emplId > 0) {
    
        // here's how simple it is to add a condition to the query.
        // Still not executing yet, just building a tree.
        predicate = predicate.And(e => e.EmployeeID == emplId);
    }
    

    据我所知,这仍然需要您知道可能的字段集(我仍然认为它很酷且值得一提)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 1970-01-01
      • 2016-12-27
      • 2021-04-07
      相关资源
      最近更新 更多