问题陈述
假设我有一个搜索人名的查询:
var result = (from person in container.people select person)
.Where(p => p.Name.Contains(some_criterion)
这将被转换为包含以下 like 子句的 SQL 查询:
WHERE NAME LIKE '%some_criterion%'
这有一些性能影响,因为数据库无法有效地使用 name 列上的索引(如果我没记错的话,索引扫描与索引搜索)。
为了解决这个问题,我可以决定只使用 StartsWith() 来代替,使用 like 子句生成查询,例如:
WHERE NAME LIKE 'some_criterion%'
这使 SQL Server 能够使用索引查找并以牺牲某些功能为代价来提供性能。
我希望能够为用户提供一个选择:默认使用 StartsWith 的行为,但如果用户想要使用 Contains() 进行搜索的“增加灵活性”,则应该使用。
我试过什么
我认为这是微不足道的,并继续在字符串上实现了一个扩展方法。但当然,LINQ 不接受这一点并抛出异常。
现在,我当然可以继续使用 if 或 switch 语句并为每种情况创建一个查询,但我更愿意“在更高级别”或更一般地解决这个问题。简而言之:由于实际应用程序的复杂性,使用 if 语句来区分用例是不可行的。这会导致大量的重复和混乱。我真的很希望能够以某种方式封装不同的行为(包含、StartsWith、EndsWith)。
问题
我应该在哪里寻找或寻找什么?这是 IQueryables 可组合性的一个案例吗?我很纳闷!