簡體   English   中英

LINQ to Entities無法識別方法'System.String [] Split(Char [])'方法,

[英]LINQ to Entities does not recognize the method 'System.String[] Split(Char[])' method,

我正在嘗試實現一種方法,其中存儲在數據庫中的活動關鍵字(用逗號分隔)與用逗號分隔的給定字符串匹配。

public List<TblActivities> SearchByMultipleKeyword(string keywords)
{
    string[] keyword = keywords.Split(',');
    var results  = (from a in Entities.TblActivities
                    where a.Keywords.Split(',').Any(p => keyword.Contains(p))
                    select a).ToList();
    return results;
}

我收到以下錯誤:

LINQ to Entities does not recognize the method 'System.String[] Split(Char[])' method,
and this method cannot be translated into a store expression.

您無法使用實體框架執行此操作,如錯誤消息所示。

但是,有選擇。

一種選擇是認識到,如果關鍵字存儲為A,B,C,D ,那么x就在那里

a.Keywords.StartsWith(x + ",") || 
a.Keywords.Contains("," + x + ",") || 
a.Keywords.EndsWith("," + x)

如果x本身不包含,那就有效。 缺點是這將對表或包含Keywords列的索引進行全面掃描。

另一種選擇是規范化您的數據庫。 畢竟,您在活動和關鍵字之間存在一對多的關系。 然后將其建模為:除了Activities表(沒有Keywords列)之外,還有一個包含兩列的KeyWords表,一個活動表的外鍵和一個keyword列。 這將允許您在keyword列上添加索引,這可以使查詢超快。

UPDATE

我重新閱讀了您的問題,並注意到您沒有測試關鍵字相等性,只是Contains 如果是這樣,你為什么不這樣做呢?

a.Keywords.Contains(x)

Entity Framework不支持String.Split 這只是因為SQL中沒有等價物。

解決方案是:

  1. 在數據庫中定義自定義函數本文提出了幾個解決方案: http//sqlperformance.com/2012/07/t-sql-queries/split-strings
  2. 使用[EdmFunction]屬性聲明此函數可由LINQ to Entities使用,如下所述: 如何從EF LINQ查詢調用DB函數?

對於不涉及太多關鍵字和太多行的查詢,您可以實現這種簡單快速的解決方案。 您可以通過反復優化結果輕松繞過Split功能,如下所示:

 public List<TblActivities> SearchByMultipleKeyword(string keywords)
 {
     string[] keywords = pKeywords.Split(',');

     var results = Entities.TblActivities.AsQueryable();    

     foreach(string k in keywords){

         results  = from a in results
                    where a.Keywords.Contains(k)
                    select a;
     }
     return results.ToList();
 }

是的,你可以這樣做:

public List<TblActivities> SearchByMultipleKeyword(string keywords)
{
    string[] keywordsSeparated = keywords.Split(',');
    var results  = (from a in Entities.TblActivities
                    where keywordsSeparated.Any(keyword => a.Keywords.Contains(keyword))
                    select a).ToList();
    return results;
}

LINQ to Entities嘗試將您的LINQ查詢轉換為SQL。 由於它不知道如何在SQL查詢中執行String.Split ,因此失敗。

這意味着除非您想編寫String.Split的SQL實現, String.Split只能在LINQ to對象中執行,這意味着您需要先將所有數據加載到內存中,然后執行where子句。 一種簡單的方法是使用.ToList()

var results  = (from a in Entities.TblActivities select a).ToList(); //Results are now in memory
results = results.Where(a =>
     a.Keywords.Split(',').Any(p => keyword.Contains(p))).ToList(); //This uses LINQ-to-objects

不確定,但你可以嘗試:由於錯誤似乎在尋找一個數組,這可能會有效。

string[] keyword = keywords.Split(new char[] {','});

var results  = (from a in Entities.TblActivities
                where a.Keywords.Split(new char[] {','}).Any(p => keyword.Contains(p))
                select a).ToList();

暫無
暫無

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

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