powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / EF. Передать в where список значений
25 сообщений из 31, страница 1 из 2
EF. Передать в where список значений
    #38391250
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На входе
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
   public class Book
    {
        public int Id { get; set; }

        public string Title { get; set; }

        //автор
        public string Author { get; set; }

        //дата публикации
        public DateTime PublishedAt { get; set; }

        public string Url { get; set; }

    }


Он связан с помощью Entity Framework 5.0 с одноименной таблицей (СУБД MS SQL 2008).
Необходимо получить список всех книг с заданными парами (Автор, Дата публикации)
Пробую сделать так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
   public class BookFilter
    {
        public string Author { get; set; }

        public DateTime PublishedAt { get; set; }
    }
...
    private List<Book> GetByFilter<TProperty>(List<BookFilter> bookFilters)
    {
        //_context - DbContext
        var query = _context.Set<Book>() as IQueryable<BookDetail>;

        return query.Where(b => bookFilters.Contains(new BookFilter{Author = b.Author, PublishedAt= b.PublishedAt})).ToList();
    }


Но при вызове метода получаю сообщение об ошибке:
Код: c#
1.
Не удалось создать константу с типом "BookFilter". В этом контексте поддерживаются только типы-примитивы ("например Int32, String и Guid")


Каким образом можно решить данную задачу?
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391265
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
Expression<Func<Book, bool>> predicate = d => d.Id > 10 && d.Author.Constains("Рихтер");



Код: c#
1.
2.
3.
4.
public IEnumerable<Book> GetByFilter(Expression<Func<Book, bool>> predicate)
{
    return context.Books.Where(predicate).ToList();
}
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391312
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУ ,
Я не понимаю, как приведенный вами пример преобразовать для списка передаваемых пар
{{2010-09-01, Рихтер}, {2008-08-08, Грубер}, {2013-05-05, Карли}}, чтобы получить список книг указанных авторов в соответствующие датой публикации.
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391322
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я тебе написал, как делать универсальный фильтр. Ну а написать сам LINQ запрос не сложно:

Код: c#
1.
2.
3.
var authors = bookFilters.Select(f => f.Author);
var dates = bookFilters.Select(f => f.PublishedAt);
var list = query.Where(b => authors.Contains(b.Author) && dates.Contains(b.PublishedAt)).ToList();
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391362
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУ ,
это уже ближе к тому, что мне нужно.
Но ваш код осуществляет поиск по двум несвязанным спискам,
в профайлере условие поиска выглядит примерно так
Код: sql
1.
([Book].[PublishedAt] IN (...) AND ([Book].[Author] IN (...)



А мне необходим поиск по одному списку связанных пар, т.е

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
declare @tmp table
(PublishedAt datetime , Author varchar(150))
insert @tmp
values
(('20100901', Рихтер), ...)

select ...
from Books b
join @tmp t on b.PublishedAt = t.PublishedAt and b.Author = t.Author
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391400
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
predicatebuilder в цикле набираете через Or пары через And... это просто "чужой велосипед", можете свой сделать...
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391453
Шамиль Фаридович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
buser , МСУ ,
Спасибо!
buser , по логике Predicatbuilder как раз то, что нужно!
Но не по исполнению. Наверное здесь лучше будет использовать хранимую процедуру и передавать туда таблицу фильтров.
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391516
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ваш вариант с процедурой, лично мне, кажется наиболее предпочтительным :)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391652
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
List<Book> GetByFilter<TProperty>(List<BookFilter> bookFilters)
{
    IQueryable<Book> result = _context.Set<Book>().Take(0);

    foreach(var filter in bookFilters)
        result = result.Concat(
            _context.Set<Book>()
               .Where(b => b.Author == filter.Author && b.PublishedAt == filter.PublishedAt)
        );

    return result.Distinct().ToList();
}
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391703
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шамиль ФаридовичА мне необходим поиск по одному списку связанных пар, т.е
Ну так бы сразу и написал. В чем сложность использовать LINQ JOIN?
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391746
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУШамиль ФаридовичА мне необходим поиск по одному списку связанных пар, т.е
Ну так бы сразу и написал. В чем сложность использовать LINQ JOIN Concat или Union?Поправил :-)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391751
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
List<Book> GetByFilter<TProperty>(List<BookFilter> bookFilters)
{
    IQueryable<Book> result = _context.Set<Book>().Take(0);

    foreach(var filter in bookFilters)
    {
        // Так лучше, а то мало ли чего...
        var filterLocal = filter;

        result = result.Concat(
            _context.Set<Book>()
               .Where(b => b.Author == filterLocal.Author && b.PublishedAt == filterLocal.PublishedAt)
        );
    }

    return result.Distinct().ToList();
}
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391767
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, мне кажется, что на выхлопе будет неимоверно жуткий план. Или ошибаюсь? :)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391772
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё-таки, как не прискорбно, я в данной задаче с временной табличкой за хранимку...
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391828
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАлексей К, мне кажется, что на выхлопе будет неимоверно жуткий план. Или ошибаюсь? :)Замена OR => UNION является типовой методикой оптимизации. Не так ли? :-)

Бывает, оптимизатор SQL сам производит такую замену, но редко. :-)

Всё зависит от количества условий. Вряд ли их будет много. Даже если такое решение не устроит, подумать о нём надо.
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391831
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУВсё-таки, как не прискорбно, я в данной задаче с временной табличкой за хранимку...Я бы не торопился отчаиваться. :-)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391851
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, таки выхлоп в студию :)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391859
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАлексей К, таки выхлоп в студию :)Выхлоп чего? Этого?

Код: sql
1.
select * from myTable where Value in (1, 2, 3) -- index scan

vs
Код: sql
1.
2.
3.
4.
5.
select * from myTable Value = 1 -- index seek
union
select * from myTable Value = 2 -- index seek
union
select * from myTable Value = 3 -- index seek


Мне кажется тут всё очевидно. Во всяком случае для меня. :-)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391918
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, а если ты батч переполнишь при большом кол-ве строк в bookFilters?
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391952
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАлексей К, а если ты батч переполнишь при большом кол-ве строк в bookFilters?~250 МБ вряд ли переполнится. Думаю, быстрее начнуться другие проблемы. :-)

Ну давай прикинем, эти условия скорее всего приходят из UI, из какого-нибудь контрола. Их там 10, 20...50, ну всяко не больше. А если это приходит не из UI, то скорее всего это архитектурная ошибка, и проблему нужно искать в другом месте.
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391956
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, 50 юнионов - это просто жестоко.
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391965
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАлексей К, 50 юнионов - это просто жестоко."Экономия на спичках" (ц)

Да сейчас даже на мобилах 4-х ядерные процы ставят. Чего бояться?
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38391973
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КМСУАлексей К, 50 юнионов - это просто жестоко."Экономия на спичках" (ц)
Я бы так не сказал. Во первых просад по планам. Подряд 50 сканов (ну или 50 индексных сиков, в зависимости от схемы и объемов) - это из области шизофрении. Как считаешь? :)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38392012
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУЯ бы так не сказал. Во первых просад по планам. Подряд 50 сканов (ну или 50 индексных сиков, в зависимости от схемы и объемов)Сканов там быть не должно, а 50 сиков, их сервер даже не заметит. Тут тонким местом скорее станет время компиляции запросов.

МСУэто из области шизофрении. Как считаешь? :)Считаю, что надо делать тест и смотреть статистику. Мне лень... :-)
...
Рейтинг: 0 / 0
EF. Передать в where список значений
    #38392019
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КСканов там быть не должно, а 50 сиков, их сервер даже не заметит. Тут тонким местом скорее станет время компиляции запросов.
Ну обычно за такой гавнокод нормальный дба честно берет противопехотную гранату и определяет ей место в кабинете ORM-щиков пионеров. Согласен? :)

Алексей КСчитаю, что надо делать тест и смотреть статистику. Мне лень... :-)
Мне тоже лень, но 50 сиков для тупейшего запроса это жирно :)
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / EF. Передать в where список значений
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]