在LINQ查询中使用Expression <Func >
我想定义一个名为CompareProductItemVendorIds
的Func
filter表达式,它可以在我的整个应用程序中使用,主要是在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
,实体已经被加载。 鉴于dbContext
或objectContext
延迟加载与显式加载的实现略有不同,我假设您使用的是显式加载。 如果将加载更改为惰性,则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的调用已被删除。