我在写 Linq 查询的过程中,遇到了需要复用 Linq 查询条件的问题,比如下面的 Linq 查询:
.Where(x?=>?x.Contains(""));
我能不能将?x => x.Contains("") ?提取出然后单独保存起来,再到后续的 linq 查询时复用,比如下面这样。
.Where(previouslySavedStatement);
回答区
你完全可以将其存放在?变量 ?中,如果你是在?IQueryable ?上扩展的话,可以这么写。
System.Linq.Expressions.Expression<Func<Foo,?bool>>?selector?=?x?=>?x.Contains("");
如果是工作在?IEumerable ?上,那就是下面这样。
Func<Foo,?bool>?selector?=?x?=>?x.Contains("");
最后将 selector 拼到?Where ?扩展方法上。
query.Where(selector);
我写了一个叫?CLinq工具包 ?就是为了解决此类问题的, 你可以在?https://www.nuget.org/packages/CLinq.EntityFramework ?上找到为 EF 所作的扩展。
接下来你可以创建任何的?query ?片段,比如下面这样。
System.Linq.Expressions.Expression<Func<Foo,?bool>>?selector?=?x?=>?x.Contains("");
然后你就可以将 selector 塞入到你的 linq 查询上。
query.AsComposable().Where(o?=>?selector.Pass(o));
除了这种简单的写法,也可以稍微复杂一些,比如条件组合查询。
query.AsComposable().Where(o?=>?selector.Pass(o)?||?anotherSelector.Pass(o));
甚至可以更复杂一些,比如嵌套。
query.AsComposable().Where(o?=>?anotherSelector.Pass(selector.Pass(o)));
如果你感兴趣,建议看看我的 CLinq 库。
点评区
我相信这是很多 Linq 新手都会遇到的一个问题,想当初 sql 可以各种无底线的拼接,但同样场景放在强类型的linq上就要复杂多了,算是?安全性?和?便捷性?上做了一个取舍吧。
|