简体   繁体   English

是否推迟执行

[英]deferred execution or not

Are below comments correct about DEFERRED EXECUTION? 以下有关DEFERRED EXECUTION的评论正确吗?

1. var x = dc.myTables.Select(r=>r);//yes
2. var x = dc.myTables.Where(..).Select(r=>new {..});//yes
3. var x = dc.myTables.Where(..).Select(r=>new MyCustomClass {..});//no

In other words, I always thought projecting custom class objects will always cause eager execution. 换句话说,我一直认为投射自定义类对象总是会引起渴望的执行。 But I couldn't find references supporting/denying it (though I am seeing results contradicting it, hence the post) 但是我找不到支持/拒绝它的参考文献(尽管我看到的结果与之相矛盾,因此该帖子)

Every statement in your question is an example of deferred execution. 您问题中的每条陈述都是延迟执行的一个例子。 The contents of the Select and Where statement have no effect on whether or not the resulting value is deferred executed or not. SelectWhere语句的内容对是否推迟执行结果值没有影响。 The Select + Where statements themselves dictate that. Select + Where语句本身决定了这一点。

As a counter example consider the Sum method. 作为反例,请考虑Sum方法。 This is always eagerly executed irrespective of what the input is. 无论输入是什么,总是急切地执行此操作。

var sum = dc.myTables.Sum(...);  // Always eager 

To prove your point, your test should look like this: 为了证明您的观点,您的测试应如下所示:

var tracer = string.Empty;
Func<inType, outType> map = r => {
       tracer = "set";
       return new outType(...);
    } 

var x = dc.myTables.Where(..).Select(map);

// this confirms x was never enumerated as tracer would be "set".
Assert.AreEqual(string.Empty, tracer);
// confirm that it would have enumerated if it could
CollectionAssert.IsNotEmpty(x);

It has been my observation that the only way to force execution right away is to force iteration of the collection. 据我观察,立即强制执行的唯一方法是强制集合的迭代。 I do this by calling .ToArray() on my LINQ. 我通过在LINQ上调用.ToArray()来实现。

Generally methods that return a sequence use deferred execution: 通常,返回序列的方法使用延迟执行:

IEnumerable<X> ---> Select ---> IEnumerable<Y>

and methods that return a single object doesn't: 返回单个对象的方法不会:

IEnumerable<X> ---> First ---> Y

So, methods like Where , Select , Take , Skip , GroupBy and OrderBy use deferred execution because they can, while methods like First , Single , ToList and ToArray doesn't because they can't. 因此,诸如WhereSelectTakeSkipGroupByOrderBy方法之所以会使用延迟执行,是因为它们可以这样做,而诸如FirstSingleToListToArray则不会,因为它们不能这样做。

from here 这里

.Select(...) is always deferred. .Select(...)始终被延迟。

When you're working with IQueryable<T> , this and other deferred execution methods build up an expression tree and this isn't ever compiled into an actual executable expression until it's iterated. 当您使用IQueryable<T> ,此和其他延迟执行方法将构建一个表达式树,并且直到对其进行迭代之前,它都不会编译成实际的可执行表达式。 That is, you need to: 也就是说,您需要:

  • Do a for-each on the projected enumerable. 对预计的可枚举进行逐项检查。
  • Call a method that internally enumerates the enumerable (ie .Any(...) , .Count(...) , .ToList(...) , ...). 调用内部枚举枚举(即一个方法.Any(...) .Count(...) .ToList(...) ,...)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM