这很有效,并且给我带来了重大的性能提升。问题是代码是UGLY。我为每个可能的参数多次重复相同的代码块。即:
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个。是否可以分解以这种方式获取参数的子句?