簡體   English   中英

linq 到實體無法識別方法

[英]linq to entities doesn't recognize a method

我有這些方法:

   public int count(
        Guid companyId, Expression<Func<T, bool>> isMatch)
    {
        var filters = new Expression<Func<T, bool>>[]{
            x => x.PriceDefinition.CompanyId == companyId,
            isMatch
        };

        return GetCount(filters);
    }

public virtual int GetCount(
            IEnumerable<Expression<Func<T, bool>>> filters)
        {
            IQueryable<T> _query = ObjectSet;

            if (filters != null)
            {
                foreach (var filter in filters)
                {
                    _query = _query.Where(filter);
                }
            }

           return _query.Count();
        }

使用時:

count(some_guid, x => x.IsMatch(entityId, inviterId, routeId, luggageTypeId));

我得到以下異常:

LINQ to Entities does not recognize the method 'Boolean IsMatch(System.Nullable`1[System.Int64], System.Nullable`1[System.Int64], System.Nullable`1[System.Int64], System.Nullable`1[System.Int64])' method, and this method cannot be translated into a store expression.

這是什么原因?
我該如何解決?

使用 linq-to-entities 時,您不能在查詢中使用任意 .NET 方法。 查詢中使用的每種方法都必須可翻譯為 SQL。 它不會幫助您返回Expession<Func<entityType, bool>>因為必須為數據庫服務器上的每條記錄評估 where 條件。

對於 EF,您的代碼意味着:

SELECT COUNT(*)
FROM ...
LEFT JOIN ...
WHERE IsMatch(....) 

因為 EF 驗證傳遞給查詢的 function 名稱,所以它會拋出異常,因為它不知道 SQL 服務器上的 IsMatch 等效項。

可以在 Linq-to-entities 中使用的唯一可能的功能是:

  • 具有到 SQL 等效項的預定義映射的規范函數
  • EdmFunctions

EdmFunctions 是用EdmFunctionAttribute標記的方法,它將 .NET function 映射到 SQL 對應項。 這些函數通常不能在常見的 .NET 代碼中執行,因為它們什么都不做或拋出異常。 它們只是用於 Linq-to-entities 的 function 占位符。 可用的 EdmFunction 包括:

  • System.Data.Objects.EntityFunctions中的預定義 EdmFunctions
  • System.Data.Objects.SqlClient.SqlFunctions 中 SQL 服務器(非緊湊)的預定義System.Data.Objects.SqlClient.SqlFunctions
  • 自定義映射的 SQL 函數 - 實體設計器中的導入向導允許您導入 SQL 函數(表值函數除外)。 You can after that write custom static .NET function and map it by EdmFunction attribute to the SQL function imported to designer.
  • 自定義 model 定義的函數 - 這是在 EDMX 文件(以 XML 格式打開)中手動編寫的特殊 function。 它是實體 SQL 的自定義可重用部分。

我已經在另一個答案中描述了如何創建 model 定義的 function 創建映射的 SQL function 非常相似 而不是在 EDMX 中手動創建Function元素,您將 map EdmFunctionAttribute屬性導入到導入的 SQLA3841AB4074D18

您正在傳遞一個調用名為IsMatch的 function 的表達式。

LINQ 到實體不知道如何處理這個 function。

我正在處理類似的問題。 在嘗試使用我的自定義方法之前,工作解決方案是使用.AsEnumerable() 你可以看看這里

實際上,您傳遞給計數的內容如下 function:

bool anonymous_delagate#123(T entity)
{
    return entity.IsMatch(a,b,c,d)
}

但是,這需要 EF 知道,在該實體上調用的方法IsMatch的真正含義是什么。

我現在唯一能想到的建議是使用某種動態表達式鍛造來動態創建這個查詢。 或者重新設計你的設計以做出不同的事情。

實際上,有一種更簡單、更正常的方法,只需幾個步驟即可完成。

  1. 制作方法IsMatch static。
  2. 直接從IsMatch返回Expression<{your entity here}, bool>
  3. 像這樣傳遞它: ({your entity here}.IsMatch({parameters}))

Rest 可以和現在一樣。

編輯:示例這將適用於特定實體,因此我將假設您的實體是Order 替換您自己的實體。

public static Expression<Func<Order, bool>> IsMatch(int id, ...) // static method, that returns filtering expression
{
     return i => i.Id == id; // create the filtering criteria
}

然后這樣稱呼它:

count(some_guid, Order.IsMatch(entityId, inviterId, routeId, luggageTypeId));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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