Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ查询的重用_C#_.net_Linq_Reusability - Fatal编程技术网

C# 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

这与结果的重用无关,更重要的是语句本身。 使用var时也不是一个错误,如中所述:

出于好奇,我想知道是否可以重用一条LINQ语句

假设我有以下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);