Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> (не)использование локальных множеств в Linq to SQL, Помогите переписать запрос 
V
    Опции темы
mihryak
Дата 31.3.2009, 01:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 1
Всего: 36



Хотелось бы фильтровать объекты по вхождению любого из задаваемых слов в одно из полей
В Linq to Objects это выглядело бы так:
Код

return documents.Where(d => words.Any(w => d.Caption.ToLower().Contains(w)));

Но Linq to Sql хоть и закономерно, но всё равно неприятно ругается
Цитата(Злая Линка)

Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.


Как бы мне переписать запрос, сохранив функциональность? Workaround'ы в голове есть (например, строго ограничить количество слов сверху, по сути захардкодив его в запросе), но это не наш метод smile
PM MAIL ICQ   Вверх
Idsa
Дата 31.3.2009, 07:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 5
Всего: 62



mihryak, это мне напомнило проблему с Contains в Entity Framework. Решается она созданием своего метода, генерирующего Expression: http://social.msdn.microsoft.com/forums/en...4-b7e4a1ab59f0/ Конечно, не очень красиво... но зато работает.

P. S. Я по ошибке не понял, что ему не нравится: метод Contains или все, кроме метода Contains? Можно попробовать заменить Contains на Any...


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
mihryak
Дата 31.3.2009, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 1
Всего: 36



Idsa, спасибо  smile 
правда, сходу не получилось заменить Equals на нужное мне выражение, дома ещё покопаюсь

linq не понравился как раз Any, применяемый к локальной коллекции, транслятор не может преобразовать проверку words.Any(w => d.Caption.ToLower().Contains(w) в соответствующий sql запрос (я тоже не могу)
PM MAIL ICQ   Вверх
Idsa
Дата 31.3.2009, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2086
Регистрация: 5.12.2006
Где: Томск

Репутация: 5
Всего: 62



Цитата(mihryak @  31.3.2009,  17:32 Найти цитируемый пост)
linq не понравился как раз Any

А, может, попробовать заменить Any на Contains? Между ними вообще есть разница?


--------------------
Мой блог: alexidsa.blogspot.com
PM MAIL ICQ   Вверх
mihryak
Дата 31.3.2009, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 1
Всего: 36



а что в условии Contains написать?
мне ведь надо перебрать сами слова, а не проверять наличие среди них какого-либо

совет инвертировать условие мне не раз уже попадался, но вот в моём случае мне не удаётся его реализовать
PM MAIL ICQ   Вверх
mihryak
Дата 31.3.2009, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 1
Всего: 36



решил задачу smile
Код

        private static Expression<Func<TElement, bool>> GetAnyWordQuery<TElement, TValue>(
            Expression<Func<TElement, TValue, bool>> valueSelector, IEnumerable<TValue> values)
        {
            if (!values.Any())
            {
                return e => false;
            }

            var contains = values.Select(
                value => (Expression)Expression.Invoke(valueSelector, new Expression[]
                        {
                            valueSelector.Parameters[0], Expression.Constant(value, typeof(TValue))
                        }));

            var body = contains.Aggregate(Expression.Or);
            var result = Expression.Lambda<Func<TElement, bool>>(body, valueSelector.Parameters[0]);

            return result;
        }

вызов
Код

documents.Where(GetAnyWordQuery<Document, string>((d, w) => d.Caption.ToLower().Contains(w), words))


вот ещё ссылка небезытересная

Idsa, держи заслуженный плюс smile
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | LINQ (Language-Integrated Query) | Следующая тема »


 




[ Время генерации скрипта: 0.0484 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.