在LINQ查询中使用Expression <Func >

我想定义一个名为CompareProductItemVendorIdsFuncfilter表达式,它可以在我的整个应用程序中使用,主要是在Entity Framework / LINQ查询中。

我已经了解到,为了能够在LINQ查询中使用此filter,我必须将其声明为Expression<Func>而不仅仅是Func 。 我理解这个的原因,这对我来说很容易。

但是我在查询中使用该表达式时遇到以下问题。

一,代码如:

 ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds) 

注意: ProductItem是一个数据库实体,其ProductItemVendors属性是导航集合。

产生错误:

`Instance参数:无法从’System.Collections.Generic.ICollection’转换为’System.Linq.IQueryable’

第二,代码如:

 var results = from v in Repository.Query() where CompareProductItemVendorIds(v) select v; 

产生错误:

‘CompareProductItemVendorIds’是’变量’,但用作’方法’

所以我有一个很好的shiny的新Expression<Func> 。 如何在LINQ查询中使用它?

ProductItem已经是一个Entity ,所以你不能使用你的Expression,你需要使用Compile ()从你的Expression>获取Func<> ,因为ProductItemVendors不再是一个IQueryable

 ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds.Compile()) 

您必须在ProductItemVendorsContext上使用Expression,如下所示:

 var item = Context.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds); 

您无法在查询语法中使用Expression,您需要使用方法sytanx

 var results = from v in Repository.Query() .Where(CompareProductItemVendorIds) select v; 

第一个案例;

 ProductItemVendor productItemVendor = ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds); 

产生错误:

 `Instance argument: cannot convert from 'System.Collections.Generic.ICollection' to 'System.Linq.IQueryable' 

发生因为它是ICollection ,实体已经被加载。 鉴于dbContextobjectContext延迟加载与显式加载的实现略有不同,我假设您使用的是显式加载。 如果将加载更改为惰性,则ProductItemVendors的类型将为IQueryable并且您尝试的内容将成功。

鉴于第二种情况,表达式必须可编译为SQL ,否则会出现许多奇怪的错误,可能这就是这种情况。

鉴于问题中的信息,很难给你更明确的帮助,我无法轻易地重新创建它。 如果你可以创建一个MWE解决方案并将其上传到某个地方,我可以看看,但我担心我在这里无法提供更多帮助。

我认为默认情况下不支持组合这样的表达式。
你可以尝试LINQKit

这是LINQKit页面的一个例子; 另一个Expression>

调用Invoke以调用最终结果的内部表达式Call Expand。 例如:

 Expression> criteria1 = p => p.Price > 1000; Expression> criteria2 = p => criteria1.Invoke (p) || p.Description.Contains ("a"); Console.WriteLine (criteria2.Expand().ToString()); 

(Invoke和Expand是LINQKit中的扩展方法。)这是输出:

 p => ((p.Price > 1000) || p.Description.Contains("a")) 

请注意,我们有一个很好的干净表达式:对Invoke的调用已被删除。