Привет всем.Я пытаюсь оптимизировать вызов Linq to Entities путем статического кэширования и повторного использования скомпилированного запроса.Запрос проверяет то же самое для переменного числа аргументов фильтра, и единственный способ скомпилировать аргументы запроса подобным образом - это явно использовать несколько аргументов (а не некоторую логику типа Contains ()), что в SQL не может бытьпараметризовано).
Это прекрасно работает и дает мне значительное повышение производительности.Проблема в том, что код ужасен.Я повторяю один и тот же кусок кода несколько раз для каждого из возможных параметров.Т.е.:
Expression<Func<Entities, string, string, string, string, IQueryable<Instrument>>> query =
(context, searchTerm0, searchTerm1, searchTerm2, searchTerm3) =>
context.Instruments
.Where(
(searchTerm0 == null ||
instr.FullName.IndexOf(searchTerm0) > -1 ||
instr.ShortName.IndexOf(searchTerm0) > -1 ||
instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm0) > -1))
&&
(searchTerm1 == null ||
instr.FullName.IndexOf(searchTerm1) > -1 ||
instr.ShortName.IndexOf(searchTerm1) > -1 ||
instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm1) > -1))
&&
(searchTerm2 == null ||
instr.FullName.IndexOf(searchTerm2) > -1 ||
instr.ShortName.IndexOf(searchTerm2) > -1 ||
instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm2) > -1))
&&
(searchTerm3 == null ||
instr.FullName.IndexOf(searchTerm3) > -1 ||
instr.ShortName.IndexOf(searchTerm3) > -1 ||
instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm3) > -1))
.Take(50);
Я думал, что смогу реорганизовать это, динамически создавая выражения фильтра, но это кажется невозможным.Я хочу сделать что-то вроде этого:
var filterExpression = (instr, searchTerm) =>
searchTerm == null ||
instr.FullName.IndexOf(searchTerm) > -1 ||
instr.ShortName.IndexOf(searchTerm) > -1 ||
instr.Strategies.OrderBy(st => st.Level).Select(st => st.Name).Take(2).Any(strat => strat.IndexOf(searchTerm) > -1);
Expression<Func<Entities, string, string, string, string, IQueryable<Instrument>>> query = (context, searchTerm0, searchTerm1, searchTerm2, searchTerm3) =>
context.Instruments
.Where(i => filterExpression(i, searchTerm0))
.Where(i => filterExpression(i, searchTerm1))
.Where(i => filterExpression(i, searchTerm2))
.Where(i => filterExpression(i, searchTerm3))
.Take(50);
Но, конечно, это не скомпилируется, потому что filterExpression является выражением и не может быть вызвано таким образом (и это не может быть просто Func, потому чтоLinq to Entities не сможет распознать его как переводимый метод)жестко закодированы и использованы повторно.То есть это не параметризованный запрос.
Я застрял, выписывая все для каждого термина?Я бы хотел поддержать максимум 14. Можно ли выделить предложения, которые принимают параметры таким образом?