这不是关于结果的重用,而是关于语句本身的更多。 使用var时也不会出现错误:LINQ to SQL: Reuse lambda expression
出于纯粹的好奇心,我想知道是否可以重用一个LINQ语句。
假设我有以下LINQ语句:
.Where(x => x.Contains(""));
是否可以提取语句x => x.Contains("")
并使用某种类型的引用来供以后使用,比方说,另一个类?
所以我可以这样称呼:.Where(previouslySavedStatement);
答案 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.Where
和Queryable.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)));
还有更多功能,但是我认为它确实很有帮助,因此请查看:)