Поисковый запрос дает исключение LINQ to SQL - PullRequest
4 голосов
/ 22 июля 2011

Для следующего запроса я получаю исключение LINQ to SQL.

var terms = "bob town".Split(' ');
var q = from m in db.Monument
    where terms.All(t => new List<string>() {
        m.Name,
        m.Street,
        m.Owner }.Any(
            p => p.Contains(t)))
    select m;

Исключение:

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

Как изменить запрос на совместимость с LINQ to SQL?


Цель

цель запроса заключается в следующем.У меня есть список поисковых терминов и база данных с объектами.Объект должен быть возвращен, если все поисковые термины являются подстрока хотя бы одного свойства.

Например.Если существует объект o с o.name="creek mill" и o.street="St. Petersroad", то поиск по «mill petersroad» должен вернуть этот объект, но поиск по «mill foobar» не должен.

Ответы [ 3 ]

1 голос
/ 22 июля 2011

Итак, настоящая проблема в том, что Linq-To-SQL не знает, как преобразовать часть Terms вашего Linq в действительный оператор SQL. Итак, вы должны изменить запрос, чтобы помочь ему.

Я предполагаю, что мы хотели бы использовать функцию Contains, чтобы получить инструкцию SQL, которая использует оператор SQL IN. Вот что я предлагаю.

var terms = "bob town".Split(' ');
var q = from m in db.Monument
    where 
            terms.Contains(m.Name)
        ||
            terms.Contains(m.Street)
        ||
            terms.Contains(m.Owner)
    select m;

Я не проверял это, но похоже, что оно должно работать и должно быть преобразовано в Linq-To-SQL.

0 голосов
/ 22 июля 2011

Я уверен, что, вероятно, есть способ сделать это с чистым LINQ, но я не уверен, действительно ли это хорошая идея: ИМХО, люди иногда склонны переваривать свои LINQ запросы ни для чего конкретногоиная причина, чем LINQ очень крутой и все, заканчивающийся запросами, которые очень трудно понять, просто взглянув на них.

Почему бы вам не реализовать метод расширения, которыйберет Monument сущностей и выясняет, соответствует ли определенный string[] вашим критериям?

Таким образом, ваше LINQ выражение не может быть проще:

var q = from m in db.Monument
where m.ContainsAllSearchTerms(terms)
select m; //readable and anyone understands right away what is going on here

Быть ContainsAllSearchTerms(this Monument m, string[] terms)соответствующий метод расширения.

0 голосов
/ 22 июля 2011

как насчет ниже. Я не пробовал, но это дает вам представление о

var terms = "bob town".Split(' ');
        var q = from m in db.Monument
                where m.Name.Split(' ').Intersect(terms).Count() > 0 ||
                        m.Street.Split(' ').Intersect(terms).Count() > 0
                select m; 

В любом случае, я думаю, что для такого вида поиска вы должны подумать об использовании полнотекстового поиска SQL, если у вас есть база данных SQL или ".net lucene", которая очень хорошо вписывается в ваш контекст

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...