问题描述
好吧
我必须建立一个谓词,以从EF5 AND 过滤器中的已知实体中选择未知数量的列,而其中未知数量的列 ONE 总是子集合中的名称.
I have to build a predicate to select an unknown number of columns from a known entity in EF5 AND filter by an unknown number of columns ONE of which will always be a name from a child collection.
所以这就是我要结束的
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
});
但是我不确定如何构建表达式的谓词
but I'm not sure how to approach building the predicate for the expression
e.Translations.FirstOrDefault(t => t.Culture.ID == "whatever").Description.Contains("q")
要选择的列和要过滤的字段以字符串数组的形式提供,在这种情况下,过滤器始终包含.
The columns to select and the fields to filter on are supplied as an array of strings, and in this instance the filter is always contains.
我熟悉构建谓词,这不是问题,更多的是,我以前从未研究过子集合,而且一天总的来说是"WTF":-)
I'm familiar with building predicates, that's not the issue, it's more I've never had to look into child collections before and I'm at a total "WTF" point of the day :-)
任何朝正确方向的推动都是最合适的.
Any and all pushes in the right direction would be most appriciated.
推荐答案
一种方法可能是使用DynamicLinq.参见 http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
One approach might be to use DynamicLinq. See http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
如果您向下看第三个查询,您应该可以执行以下操作:
If you look at the third query down, you should be able to do something like:
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
,可以在使用字符串之前使用构建字符串所需的任何表达式.对于包含"子句,它有点复杂-请参阅此处描述的方法-
Regarding select an unknown number of columns from a known entity in EF5 AND filter by an unknown number of columns
, you could use whatever expression is required to build your string prior to using it. For the 'contains' clause it is a bit more complex - please see the methods described here - How to write String.Contains in Dynamic Linq
由于我没有访问EF5的权限,因此我尚未进行实际测试,但似乎DynamicLinq存在基于EF5的问题(因此应该可以使用)-
I haven't actually tested this as I don't have access to EF5, but it looks like there are EF5 based questions for DynamicLinq (so it should work) - https://stackoverflow.com/questions/9929396/entity-framework-5-0-performance-with-dyanmic-linq
此外,我应该指出,我更愿意为此目的使用PredicateBuilder,但我相信您将无法不事先知道字段名称/使用某种形式的反射(请参阅).也值得肯定这个答案( https://stackoverflow.com/a/2497335/201648 )方法.
Also, I should point out that I would prefer to use PredicateBuilder for this purpose, but I believe you will be unable to without knowing the fieldnames in advance/using some sort of reflection (see Using Dynamic Column Names in a Linq Query). It is also worth acknowledging this answer (https://stackoverflow.com/a/2497335/201648) which suggests the above approach.
此外,也可以使用lambda设置字段的条件规则,如下所述: http://www.codeproject.com/Articles/28580/LINQ-and-Dynamic-Predicate-Construction-at-Runtime
Also, it is possible to setup conditional rules for fields using lambdas as described here: 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);
}
据我所知,这仍然需要您知道可能的字段集(我仍然认为它很酷,值得一提).
This would still require you to know the possible set of fields as far as I can see (I still think its cool and worth a mention).
这篇关于EF5中的动态谓词构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!