.NET实体框架 - IEnumerable VS. IQueryable的 [英] .NET Entity Framework - IEnumerable VS. IQueryable

查看:147
本文介绍了.NET实体框架 - IEnumerable VS. IQueryable的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请参阅这一行代码。这是一个存储过程的调用,它返回一个 ObjectResult< long?> 。为了提取长值,我添加了选择:

Please see this line of code. This is an invocation of a stored procedure, which returns an ObjectResult<long?>. In order to extract the long values I added the Select:

dbContext.FindCoursesWithKeywords(keywords).Select(l => l.Value);

根据智能感知,此选择返回 IEnumerable< long>

Based on intellisense this Select returns IEnumerable<long>.

我不知道我是否在某个地方阅读它,也可能习惯了这个假设 - 我一直认为,当EF API返回一个 IEnumerable (而不是 IQueryable )那么这意味着结果已经实现。意思是他们从数据库中被拉出来。

I'm not sure whether I read it somewhere or maybe just got used to this assumption - I always thought that when the EF API returns an IEnumerable (and not IQueryable) then this means that the results have been materialized. Meaning they've been pulled from the database.

我今天发现我错了(或者也许这是一个错误)。我不断收到错误

I found out today that I was wrong (or maybe that's a bug?). I kept getting the error


新会话不允许,因为会话中还有其他线程
运行

"New transaction is not allowed because there are other threads running in the session"

基本上,这个错误告诉你,你正在尝试保存更改,而数据库读取器仍在读取记录。

Basically, this error tells you that you're trying to save changes while the db reader is still reading records.

最后我解决了(我认为是一个长镜头),并添加了 ToArray()调用实现 IEnumerable< ; long> ...

Eventually I solved it by (what I considered a long shot) and added ToArray() call to materialize the IEnumerable<long>...

所以 - 底线 - 我应该期望 IEnumerable 结果从EF包含尚未实现的结果?如果是,那么有没有办法知道一个 IEnumerable 是否已实现?

So - the bottom line - should I expect IEnumerable results from EF to contain results that haven't materialized yet? If yes then is there a way to know whether an IEnumerable has been materialized or not?

谢谢并道歉这是duhhh问题之一...:)

Thanks and apologies if this is one of those 'duhhh' questions... :)

推荐答案

IQueryable 在使用Linq-to-entities时使用=您正在构建应用程序中的声明式LINQ查询,这将被LINQ提供程序解释为SQL并在服务器上执行。一旦查询执行(迭代),它将变为IEnumerable,并且对象将根据需要进行实例化=不会立即。

IQueryable is used when you are using Linq-to-entities = you are building declarative LINQ query in your application which will be interpreted by LINQ provider as SQL and executed on the server. Once the query is executed (iterated) it will turn to become IEnumerable and objects will be materialized as needed for iteration = not immediately.

一旦您调用存储过程,您就不会因为您的应用程序中没有内置的声明式查询,因此使用Linq-to-entities。查询/ SQL已经存在于数据库服务器上,而您正在调用它。这将返回 IEnumerable ,但是再次不会立即实现所有结果。结果将重现。当您明确要求提取对象时,这是数据库游标/或.NET数据读取器的原理。

Once you call stored procedure you are not using Linq-to-entities because there is no declarative query built in your application. The query / SQL already exists on database server and you are just invoking it. This will return IEnumerable but again it will not materialize all results immediately. Results will be materialized as iterated. This is principle of database cursor / or .NET data reader when you explicitly ask for fetching object.

所以如果你这样打电话:

So if you call something like this:

foreach (var keyword in dbContext.FindCoursesWithKeywords(keywords)
                                 .Select(l => l.Value))
{
    ...   
}

你一个一个地获取课程(btw。为什么要加载整个课程,如果你只对关键字感兴趣?)。在您完成或中断循环之前,您的数据读取器将被打开以获取记录。

You are fetching courses one by one (btw. why to load whole course if you are interested only in keywords?). Until you complete or break the loop your data reader is opened to fetch records.

如果您改为:

foreach (var keyword in dbContext.FindCoursesWithKeywords(keywords)
                                 .ToList() // or ToArray 
                                 .Select(l => l.Value))
{
    ...
}

您将强制查询要立即实现所有结果,循环将在内存中执行,而不是打开数据库读取器。

You will force query to materialize all results immediately and loop will perform on collection in memory instead of opened database reader.

IEnumerable IQueryable 不是如何获取数据的方式,因为 IQueryable IEnumerable 。不同之处在于支持构造(必须实现这些接口)。

Difference between IEnumerable and IQueryable is not in the way how data are fetched because IQueryable is IEnumerable. The difference is in backing construct (something must implement these interfaces).

这篇关于.NET实体框架 - IEnumerable VS. IQueryable的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆