LINQ to Entities не распознает метод метода System.String [] Split (Char []),

c# string linq

11797 просмотра

6 ответа

Я пытаюсь реализовать метод, в котором ключевые слова, хранящиеся в базе данных для деятельности (разделенные запятой), совпадают с строкой выдачи, разделенной запятой.

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.
Автор: rikket Источник Размещён: 12.11.2019 09:44

Ответы (6)


3 плюса

Решение

Для запросов, которые не содержат слишком много ключевых слов и слишком много строк, вы можете реализовать это простое и быстрое решение. Вы можете легко обойти функцию разделения, многократно уточняя свои результаты следующим образом:

 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();
 }
Автор: cmaduro Размещён: 23.07.2014 06:56

11 плюса

Вы не можете сделать это с помощью Entity Framework, как говорится в сообщении об ошибке.

Однако есть варианты.

Один из вариантов заключается в том, чтобы понять, что, если ключевые слова хранятся как A,B,C,D, то xтам, если

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

Это работает, если xне содержит ,себя. Недостатком является то, что при этом будет выполнено полное сканирование таблицы или индекса, содержащего Keywordsстолбец.

Другой вариант - нормализовать вашу базу данных. В конце концов, у вас есть отношение один ко многим между активностью и ключевым словом. Затем смоделируйте его так: помимо Activitiesтаблицы (без столбца Ключевые слова), есть KeyWordsтаблица с двумя столбцами, внешний ключ к вашей таблице действий и keywordстолбец. Это позволит вам добавить индекс для keywordстолбца, который может сделать запрос очень быстрым.

ОБНОВИТЬ

Я перечитал ваш вопрос и заметил, что вы проверяете не равенство ключевых слов, а просто Contains. Если так, почему бы тебе просто не сделать следующее?

a.Keywords.Contains(x)
Автор: Kris Vandermotten Размещён: 29.05.2014 09:29

4 плюса

String.Splitне поддерживается Entity Framework. Это просто потому, что в SQL нет эквивалента.

Решение:

  1. определить пользовательскую функцию в базе данных В этой статье предлагается несколько решений: http://sqlperformance.com/2012/07/t-sql-queries/split-strings
  2. объявить эту функцию пригодной для использования LINQ to Entities, используя [EdmFunction]атрибут, как описано здесь: Как вызвать функцию DB из запроса EF LINQ?
Автор: nlips Размещён: 31.05.2014 01:10

3 плюса

Да, вы можете сделать это так:

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;
}
Автор: Grigor Margaritov Размещён: 23.12.2016 11:46

0 плюса

LINQ to Entities пытается перевести ваш запрос LINQ в SQL. Поскольку он не знает, как это сделать String.Splitв SQL-запросе, он терпит неудачу.

Это означает, что если вы не хотите писать реализацию SQL String.Split, вы можете делать это только в LINQ для объектов, что означает, что вам сначала нужно загрузить все свои данные в память, а затем выполнить 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
Автор: Ben Aaronson Размещён: 29.05.2014 09:22

-4 плюса

Не уверен, но вы можете попробовать: так как ошибка, похоже, ищет массив, это может сработать.

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();
Автор: n4gy3 Размещён: 29.05.2014 09:39
32x32