LINQ содержит одно совпадение из массива строк - PullRequest
9 голосов
/ 09 сентября 2011

Не удается заставить это работать:

    /// <summary>
    /// Retrieve search suggestions from previous searches
    /// </summary>
    public static string[] getSearchSuggestions(int SectionID, string Query)
    {
        string[] Suggestions;
        string[] Words = Query.Split(' ');

        using (MainContext db = new MainContext())
        {
            Suggestions = (from c in db.tblSearches
                        where c.SectionID == SectionID &&
                        Words.Any(w => c.Term.Contains(w))
                        select c.Term).ToArray();
        }

        return Suggestions;
    }

Я получаю:

System.NotSupportedException: Локальная последовательность не может использоваться в реализациях операторов запросов LINQ to SQL, кроме оператора Contains.

Я хочу вернуть записи, где поле c.Term содержит любое из слов в массиве Words. Я также хотел бы, чтобы это было упорядочено по общему количеству матчей, но это кажется действительно трудным! Я нашел этот MSDN . Но я не могу заставить его работать и с моим запросом. Также нашел это, но он не работает .

Ответы [ 3 ]

6 голосов
/ 09 сентября 2011

Хорошо, после того, как я достаточно отключился, я понял, что проблема не в «Любой» или «Содержит».Linq to SQL не любит, когда вы комбинируете локальную последовательность (слова) с коллекцией SQL (db.tblSearches).Поэтому, чтобы выполнить это, вы должны разбить его на 2 отдельных запроса.

public static string[] getSearchSuggestions(int SectionID, string Query)
{
    string[] Suggestions;
    string[] Words = Query.Split(' ');

    using (MainContext db = new MainContext())
    {
        string[] all = (from c in db.tblSearches
                    where c.SectionID == SectionID
                    select c.Term).ToArray();

        Suggestions = (from a in all
                       from w in Words
                       where a.Contains(w)
                       select a).Distinct().ToArray();


    }

    return Suggestions;
}

Имейте в виду, что во втором запросе Contains чувствителен к регистру, поэтому вам, возможно, придетсядобавьте метод расширения без учета регистра или перейдите к старой школе и пните их .ToUpper().Я запустил это в 4.0 в одном из моих контекстов, и он вернул все 88 строк правильно (из возможных 9814).Хотя это была тщательная PITA.Определенно +1 по этому вопросу.

Редактировать: Добавлено .Distinct() к окончательному ответу.

3 голосов
/ 09 сентября 2011

Сначала преобразуйте ваш массив в список,

 List<string> wordList = Words.ToList();

затем измените ваш запрос linq следующим образом:

    Suggestions = (from c in db.tblSearches                           
where c.SectionID == SectionID &&                           
Words.Contains(c.Term)                           
select c.Term).ToArray();  

Мне кажется, я вижу твою проблему. В исходном запросе вы используете c.Term.Contains () ... Contains - это метод расширения, который необходимо вызывать для объекта, который реализует Enumerable, чтобы вы не могли вызывать его в поле, которое вы возвращаете из вызова базы данных. Вот почему другой пользователь, ответивший на ваш вопрос, сказал, что вам нужно перевернуть вещи в ваших контейнерах, потому что он никогда не позволит вам сделать этот вызов на c.Terms.

2 голосов
/ 09 сентября 2011

Вам необходимо перевернуть ваш заказ в условии Contains:

        Suggestions = (from c in db.tblSearches 
                    where c.SectionID == SectionID && 
                    Words.Contains(w => c.Term) 
                    select c.Term).ToArray(); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...