Re: Сложная выборка
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.12.24 03:11
Оценка: 5 (1) +2
Здравствуйте, peer, Вы писали:

P>Привет


P>Есть приложение .net + mssql и есть таблица с 50 полями и нужно сделать выборку из этой таблицы на основании фильтра который состоит из 15 параметров (поля этой таблицы)

P>Можно конечно сделать перебор всех параметров фильтра типа
P>
P>if (filter.Param1 != null)
P>   context.Entities.Where(a => a.Param1 = filter.Param1)
P>if (filter.Param2 != null)
P>   context.Entities.Where(a => a.Param2 = filter.Param2)
P>

Я не эксперт по EF, но код выглядит некорректным.
Вы, наверное, имели в виду что-то вроде:
var source = context.Entities;
if (filter.Param1 != null)
   source = source.Where(a => a.Param1 = filter.Param1);
if (filter.Param2 != null)
   source = source.Where(a => a.Param2 = filter.Param2);
...

Это вполне себе элегантно. Более элегантные вещи потребуют метапрограммирования, и оправданы тогда, когда у вас есть более-менее сложная модель. Например, у вас таких таблиц по 15 полей — много, и поддерживать вручную все вот эти N*M if (filter.StartDate != null) становится трудно. Тогда можно навелосипедить кодогенерацию, которая
1. Порождает классы фильтров для каждой Entity
2. Порождает код по генерации предиката для Entity на основе созданного для неё фильтра
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Сложная выборка
От: RushDevion Россия  
Дата: 13.12.24 18:34
Оценка: 5 (1)
P>
P>if (filter.Param1 != null)
P>   context.Entities.Where(a => a.Param1 = filter.Param1)
P>if (filter.Param2 != null)
P>   context.Entities.Where(a => a.Param2 = filter.Param2)
P>

Вполне нормальный вариант.
Простой в реализации, понятный в поддержке и легко расширяемый (скажем, по условиям вида !=, contains, starts with и т.п.)

Можно, конечно, заморочиться и родить что-то такое:
public static Expression<Func<Entity, bool>> BuildFilterExpression(Filter filter) {
 // TODO: 
 // рефлексией вытягиваем из filter все не null-свойства
 // и в предположении, что имя свойства в фильтре = имя свойства в Entity, собираем нужный Expression
}

// Тогда будет так:
context.Entitites.Where(BuilFilterExpression(filter))

Но городить подобное ради разовой задачи, имхо, перебор.
Re[2]: Сложная выборка
От: Sharov Россия  
Дата: 16.12.24 08:42
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Я не эксперт по EF, но код выглядит некорректным.

S>Вы, наверное, имели в виду что-то вроде:
S>
S>var source = context.Entities;
S>if (filter.Param1 != null)
S>   source = source.Where(a => a.Param1 = filter.Param1);
S>if (filter.Param2 != null)
S>   source = source.Where(a => a.Param2 = filter.Param2);
S>...
S>


Если уж совсем быть корректным, тогда source = source.Where(a => a.Param1 == filter.Param1)

PS: Как писать подобные запросы не важно, важно чтобы выполнялось эффективно. Т.е. чтобы в бд обращалось один раз.
Кодом людям нужно помогать!
Отредактировано 16.12.2024 8:44 Sharov . Предыдущая версия .
Сложная выборка
От: peer  
Дата: 13.12.24 13:07
Оценка:
Привет

Есть приложение .net + mssql и есть таблица с 50 полями и нужно сделать выборку из этой таблицы на основании фильтра который состоит из 15 параметров (поля этой таблицы)
Можно конечно сделать перебор всех параметров фильтра типа

if (filter.Param1 != null)
   context.Entities.Where(a => a.Param1 = filter.Param1)
if (filter.Param2 != null)
   context.Entities.Where(a => a.Param2 = filter.Param2)


но может есть что-то элегантнее?

Почему так много полей в таблице не спрашивать)
Re: Сложная выборка
От: GarryIV  
Дата: 13.12.24 18:35
Оценка:
Здравствуйте, peer, Вы писали:

P>Привет


P>Есть приложение .net + mssql и есть таблица с 50 полями и нужно сделать выборку из этой таблицы на основании фильтра который состоит из 15 параметров (поля этой таблицы)

P>Можно конечно сделать перебор всех параметров фильтра типа

P>но может есть что-то элегантнее?


если не писать context.Entities.Where 15 раз то будет уже хорошо (сделать filter.toPredicate() или типа того)
WBR, Igor Evgrafov
Re[2]: Сложная выборка
От: Qulac Россия  
Дата: 13.12.24 20:17
Оценка:
Здравствуйте, RushDevion, Вы писали:

P>>
P>>if (filter.Param1 != null)
P>>   context.Entities.Where(a => a.Param1 = filter.Param1)
P>>if (filter.Param2 != null)
P>>   context.Entities.Where(a => a.Param2 = filter.Param2)
P>>

RD>Вполне нормальный вариант.
RD>Простой в реализации, понятный в поддержке и легко расширяемый (скажем, по условиям вида !=, contains, starts with и т.п.)

RD>Можно, конечно, заморочиться и родить что-то такое:

RD>
RD>public static Expression<Func<Entity, bool>> BuildFilterExpression(Filter filter) {
RD> // TODO: 
RD> // рефлексией вытягиваем из filter все не null-свойства
RD> // и в предположении, что имя свойства в фильтре = имя свойства в Entity, собираем нужный Expression
RD>}

RD>// Тогда будет так:
RD>context.Entitites.Where(BuilFilterExpression(filter))
RD>

RD>Но городить подобное ради разовой задачи, имхо, перебор.

У нас используется второй вариант, часть которого писал я. А так я вообще за первый всегда, потому что он проще. Если лень самому писать много if, то можно попросить capilot — он накатает.
Программа – это мысли спрессованные в код
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.