0

好的,

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

所以这就是我需要结束的

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”点:-)

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

4

1 回答 1

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,您可以在使用之前使用构建字符串所需的任何表达式。对于“包含”子句,它有点复杂 - 请参阅此处描述的方法 -如何在动态 Linq 中编写 String.Contains

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

另外,我应该指出,我更愿意为此目的使用 PredicateBuilder,但我相信如果不提前知道字段名/使用某种反射(请参阅在 Linq 查询中使用动态列名),您将无法做到这一点。也值得承认这个答案(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);
}

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

于 2013-02-15T12:13:36.527 回答