Am I misunderstanding LINQ to SQL .AsEnumerable()?
考虑此代码:
1 2 3 4 5 6 7 | var query = db.Table .Where(t => SomeCondition(t)) .AsEnumerable(); int recordCount = query.Count(); int totalSomeNumber = query.Sum(); decimal average = query.Average(); |
假设
我是否遗漏了一些关于
调用
要强制执行查询,必须调用
对。
好吧,你走对了。问题是,一个
贾斯汀·尼斯纳的回答是完美的。
我只想在这里引用一个msdn解释:.net语言集成的关系数据查询
The AsEnumerable() operator, unlike ToList() and ToArray(), does not cause execution of the query. It is still deferred. The AsEnumerable() operator merely changes the static typing of the query, turning a IQueryable into an IEnumerable, tricking the compiler into treating the rest of the query as locally executed.
我希望这就是所谓的:
IQueryable-methods to the IEnumerable-methods (ie changing from LINQ to SQL to LINQ to Objects
一旦它是对象的LINQ,我们就可以应用对象的方法(例如toString())。这是关于Linq的一个常见问题的解释-为什么Linq to Entities不能识别方法"System.String ToString()?
根据AsEnumerable-codeblog.jonsket的说法,在以下情况下,
some aspects of the query in the database, and then a bit more manipulation in .NET – particularly if there are aspects you basically can’t implement in LINQ to SQL (or whatever provider you’re using).
它还说:
All we’re doing is changing the compile-time type of the sequence which is propagating through our query from IQueryable to IEnumerable – but that means that the compiler will use the methods in Enumerable (taking delegates, and executing in LINQ to Objects) instead of the ones in Queryable (taking expression trees, and usually executing out-of-process).
最后,还可以看到这个相关的问题:返回IEnumerable与IQueryable
我假设ToList强制Linq从数据库中获取记录。然后,当您执行继续计算时,它们是针对内存中的对象执行的,而不是涉及数据库。
将返回类型保留为可枚举的意味着在执行计算的代码调用它之前,不会提取数据。我想这其中的附带作用是数据库被命中三次——每次计算一次,数据不会持久保存到内存中。