C# LINQ查询的重用
这与结果的重用无关,更重要的是语句本身。 使用var时也不是一个错误,如中所述: 出于好奇,我想知道是否可以重用一条LINQ语句 假设我有以下LINQ语句:C# LINQ查询的重用,c#,.net,linq,reusability,C#,.net,Linq,Reusability,这与结果的重用无关,更重要的是语句本身。 使用var时也不是一个错误,如中所述: 出于好奇,我想知道是否可以重用一条LINQ语句 假设我有以下LINQ语句: .Where(x => x.Contains("")); 是否可以提取语句x=>x.Contains(“”),并使用某种形式的引用以供以后在另一个类中使用 所以我可以这样称呼它:.Where(previouslySavedStatement)您可以将其存储在变量中。如果您使用的是IQueryable,请使用: System.Linq
.Where(x => x.Contains(""));
是否可以提取语句x=>x.Contains(“”)
,并使用某种形式的引用以供以后在另一个类中使用
所以我可以这样称呼它:
.Where(previouslySavedStatement)代码>您可以将其存储在变量中。如果您使用的是IQueryable
,请使用:
System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");
Func<Foo, bool> selector = x => x.Contains("");
并在查询中使用它:
query.Where(selector);
视情况而定。有两个Where
方法,Enumerable.Where
和Queryable.Where
。如果将.Where
应用于IEnumerable
则调用第一个,如果将其应用于IQueryable
则调用第二个
由于可枚举。其中
接受函数
,因此它不可重用。因为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;
可以,您可以编写一个包含要重用的查询的函数,该函数接受并返回IQueryable
我写了一个库来解决这个问题,它叫做CLinq,您可以在这里找到EntityFramework的实现:
它允许创建查询片段,并在linq查询中的任何地方使用它们。按照Hamid的示例,创建以下表达式:
var query2 = x.Where(funcExpr);
System.Linq.Expressions.Expression选择器=x=>x.Contains(“”)代码>
现在,您可以在linq查询中的任何地方使用此查询,如下所示:
query.AsComposable().Where(o=>selector.Pass(o))代码>
除此简单示例外,您还可以组合查询片段:
query.AsComposable().Where(o=>selector.Pass(o)|另一个selector.Pass(o))代码>
甚至将它们合并在一起:
query.AsComposable().Where(o=>anotherSelector.Pass(selector.Pass(o))代码>
还有一些特性,但我认为它确实很有用,所以请查看:)将其放入变量中Func=x=>x.contains(“”)代码>@wudzik这不是重复的。重复引用指的是重复使用结果,问题询问的是重复使用查询本身。@Shlomo抱歉,理解错误的问题,重新打开Func-previouslySavedStatement=x=>x.Contains(“”)
或表达式
如果源是IQueryable
。如果您使用的是IEnumerable
而不是IQueryable
,则可能会将FYI复制到@Blaatz0r,您只会使用函数选择器=…
,但是如果你使用的是IQueryable
你最想使用的是表达式
版本。@ScottChamberlain我的大部分陈述都是IEnumerable的,所以谢谢你的建议up@Blaatz0r如果您有表达式版本,还可以通过执行Func selector2=selector.Compile()将其转换为委托代码>,你不能从一个代表转到另一个表达式。是的,我甚至读了接受的答案,我甚至也读了问题。我甚至相信我的答案比公认的答案更好地回答了这个问题。var methodExpr=(MethodCallExpression)expr
似乎没有MethodCallExpression methodExpr=expr那么干净代码>+1这并没有直接回答OP的问题,但这是解决他的问题的一个更好的方法(不过,为什么选择IQueryable
而不是IEnumerable
?)问题中没有指定数据类型,但它确实提到了“LINQ to SQL”,并且在标题中有“query”,所以我猜IQueryable:-)
public IQueryable<T> ContainsEmpty(IQueryable<T> query)
{
return query.Where(x => x.Contains(""));
}
query1 = ContainsEmpty(query1);
query2 = ContainsEmpty(another);