我在写 Linq 查询的过程中,遇到了需要复用 Linq 查询条件的问题,比如下面的 Linq 查询:
.Where(x => x.Contains(""));
我能不能将 x => x.Contains("")
提取出然后单独保存起来,再到后续的 linq 查询时复用,比如下面这样。
.Where(previouslySavedStatement);
回答区
-
Hamid Pourjam
你完全可以将其存放在 变量
中,如果你是在 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);
-
crazy_crank
我写了一个叫 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上就要复杂多了,算是 安全性 和 便捷性 上做了一个取舍吧。