EF5中的动态谓词构建

时间:2013-02-14 05:53:58

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

确定,

我必须构建一个谓词,用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”点: - )

任何和所有推动正确方向的人都会受到最大程度的关注。

1 个答案:

答案 0 :(得分:2)

一种方法可能是使用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,您可以在使用之前使用构建字符串所需的任何表达式。对于'contains'子句,它有点复杂 - 请参阅此处描述的方法 - How to write String.Contains in Dynamic Linq

我实际上没有对此进行测试,因为我无法访问EF5,但看起来有一些基于EF5的DynamicLinq问题(所以它应该可以工作) - 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);
}

这仍然需要你知道我可以看到的可能的字段集(我仍然觉得它很酷,值得一提)。