[英]Using Expression<Func<>> in a LINQ Query
我想定義一個名為CompareProductItemVendorIds
的Func<ProductItemVendor, bool>
過濾器表達式,它可以在我的應用程序中使用,主要是在Entity Framework / LINQ查詢中。
我已經了解到,為了能夠在LINQ查詢中使用此過濾器,我必須將其聲明為Expression<Func<>>
而不僅僅是Func<>
。 我理解這個的原因,這對我來說很容易。
但是我在查詢中使用該表達式時遇到以下問題。
首先,代碼如:
ProductItem.ProductItemVendors.FirstOrDefault(CompareProductItemVendorIds)
注意: ProductItem
是一個數據庫實體,其ProductItemVendors
屬性是導航集合。
產生錯誤:
`Instance參數:無法從'System.Collections.Generic.ICollection'轉換為'System.Linq.IQueryable'
第二,代碼如:
var results = from v in Repository.Query<ProductItemVendor>()
where CompareProductItemVendorIds(v)
select v;
產生錯誤:
'CompareProductItemVendorIds'是'變量',但用作'方法'
所以我有一個很好的閃亮的新Expression<Func<>>
。 如何在LINQ查詢中使用它?
ProductItem
已經是一個Entity
,所以你不能使用你的Expression,你需要使用Compile ()從你的Expression<Func<>>
獲取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<ProductItemVendor>()
.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<Func<>>
調用Invoke以調用最終結果的內部表達式Call Expand。 例如:
Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000; Expression<Func<Purchase,bool>> 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的調用已被刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.