重用LINQ查询

时间:2015-12-17 14:42:47

标签: c# .net linq reusability

这不是关于结果的重用,而是关于语句本身的更多。 使用var时也不会出现错误:LINQ to SQL: Reuse lambda expression

出于纯粹的好奇心,我想知道是否可以重用一个LINQ语句。

假设我有以下LINQ语句:

.Where(x => x.Contains(""));

是否可以提取语句x => x.Contains("")并使用某种类型的引用来供以后使用,比方说,另一个类?

所以我可以这样称呼:.Where(previouslySavedStatement);

4 个答案:

答案 0 :(得分:38)

您可以将其存储在变量中。如果您正在使用IQueryable,请使用:

System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");

如果您使用IEnumerable,请使用:

Func<Foo, bool> selector = x => x.Contains("");

在查询中使用它:

query.Where(selector);

答案 1 :(得分:8)

是的,您可以编写一个包含您要重用的查询的函数,该函数接收并返回IQueryable&lt; T&gt;

   public IQueryable<T> ContainsEmpty(IQueryable<T> query)
   {
       return query.Where(x => x.Contains(""));
   }

现在你可以重复使用它了:

   query1 = ContainsEmpty(query1);
   query2 = ContainsEmpty(another);

答案 2 :(得分:5)

这取决于。有两种Where方法,Enumerable.WhereQueryable.Where。如果您将.Where应用于IEnumerable而不是第一个IQueryable,则如果您将其应用于Enumerable.Where,则会调用第二个Func

由于Queryable.Where接收var x = new List<string>().AsQueryable(); var query = x.Where (n => n.Contains("some string")); //Extract the lambda clause var expr = query.Expression; var methodExpr = (MethodCallExpression)expr; var quoteExpr = (UnaryExpression)methodExpr.Arguments[1]; var funcExpr = (Expression<Func<string, bool>>)quoteExpr.Operand; ,因此不可重复使用。由于var query2 = x.Where(funcExpr); 接受表达式,因此它是可重用的。你可以这样做:

cards

稍后您可以重新应用where表达式:

xml:

答案 3 :(得分:0)

我写了一个库来解决这个问题,它叫做CLink,您可以在这里找到EntityFramework的实现:https://www.nuget.org/packages/CLinq.EntityFramework

它允许创建查询片段,并在linq查询中的任何地方使用它们。按照Hamid的示例,创建以下表达式:

System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");

您现在可以在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)));

还有更多功能,但是我认为它确实很有帮助,因此请查看:)