簡體   English   中英

使用表達式 <Func<> &gt;在LINQ查詢中

[英]Using Expression<Func<>> in a LINQ Query

我想定義一個名為CompareProductItemVendorIdsFunc<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 ,實體已經被加載。 鑒於dbContextobjectContext延遲加載與顯式加載的實現略有不同,我假設您使用的是顯式加載。 如果將加載更改為延遲,則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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM