实体框架可查询异步 [英] Entity Framework Queryable async
问题描述
我正在使用实体框架6和我的控制器方法之一有的某些Web API的东西是获取全部即希望从我的数据库收到表的内容为的IQueryable<实体GT;
。在我的仓库我想知道是否有任何有利的理由,因为我是新来使用EF与异步做到这一点是异步的。
I'm working on some some Web API stuff using Entity Framework 6 and one of my controller methods is a "Get All" that expects to receive the contents of a table from my database as IQueryable<Entity>
. In my repository I'm wondering if there is any advantageous reason to do this asynchronously as I'm new to using EF with async.
基本上它归结为
public async Task<IQueryable<URL>> GetAllUrlsAsync()
{
var urls = await context.Urls.ToListAsync();
return urls.AsQueryable();
}
VS
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
请问异步版本实际上这里产生的性能优势还是我被投射到列表第一(使用异步介意你),然后将IQueryable的?招致不必要的开销
Will the async version actually yield performance benefits here or am I incurring unnecessary overhead by projecting to a List first (using async mind you) and THEN going to IQueryable?
推荐答案
嗯......什么?好吧,让我们开始。
Well... What??? Okay, let's start.
- 您不明白EF工作原理
- 您不知道如何异步/等待的作品。
那么,让我们来看看这个code:
About Entity Framework
So, let's look at this code:
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
和例如,它的用法:
repo.GetAllUrls().Where(u => <condition>).Take(10).ToList()
会发生什么呢?
What happens there?
- 我们越来越
的IQueryable
对象使用(而不是访问数据库尚)repo.GetAllUrls()
- 我们创建一个使用
。凡(U =&GT与指定的条件一个新的
的IQueryable
对象;&lt;条件&GT; - 我们创建指定分页限制使用
新的
的IQueryable
对象。取(10) - 我们检索使用数据库结果
.ToList()
。我们的的IQueryable
对象被编译为SQL(如选择顶部10 *从URL中其中&lt;条件&gt;
)。和数据库可以使用索引,SQL服务器让你从你的数据库(而不是存储在数据库中的所有网址十亿) 只有10个对象
- We are getting
IQueryable
object (not accessing database yet) usingrepo.GetAllUrls()
- We create a new
IQueryable
object with specified condition using.Where(u => <condition>
- We create a new
IQueryable
object with specified paging limit using.Take(10)
- We retrieve results from database using
.ToList()
. OurIQueryable
object is compiled to sql (likeselect top 10 * from Urls where <condition>
). And database can use indexes, sql server send you only 10 objects from your database (not all billion urls stored in database)
好吧,让我们来看看第一个code:
Okay, let's look at first code:
public async Task<IQueryable<URL>> GetAllUrlsAsync()
{
var urls = await context.Urls.ToListAsync();
return urls.AsQueryable();
}
通过使用同样的例子,我们得到了:
With the same example of usage we got:
- 我们使用的是加载在内存存储在数据库中的所有十亿网址
等待context.Urls.ToListAsync();
- 我们得到了内存溢出。正确的方式杀死你的服务器
为什么异步/的await是pferred使用$ P $?让我们来看看这个code:
About async/await
Why async/await is preferred to use? Let's look at this code:
var stuff1 = repo.GetStuff1ForUser(userId);
var stuff2 = repo.GetStuff2ForUser(userId);
return View(new Model(stuff1, stuff2));
在这里会发生什么事?
What happens here?
- 启动1号线
VAR stuff1 = ...
- 我们将请求发送到SQL Server,我们wan't得到一些stuff1为
用户id
- 我们等待(当前线程被阻塞)
- 我们等待(当前线程被阻塞)
- ...
- SQL SERVER发送给我们回应
- 我们移动到2号线
VAR stuff2 = ...
- 我们将请求发送到SQL Server,我们wan't得到一些stuff2为
用户id
- 我们等待(当前线程被阻塞)
- ,再次
- ...
- SQL SERVER发送给我们回应
- 我们渲染视图
因此,让我们来看看它的一个异步版本:
So let's look to an async version of it:
var stuff1Task = repo.GetStuff1ForUserAsync(userId);
var stuff2Task = repo.GetStuff2ForUserAsync(userId);
await Task.WhenAll(stuff1Task, stuff2Task);
return View(new Model(stuff1Task.Result, stuff2Task.Result));
在这里会发生什么事?
What happens here?
- 我们将请求发送到SQL Server以获取stuff1(1号线)
- 我们将请求发送到SQL Server以获取stuff2(2号线)
- 我们等待从SQL Server响应,但当前线程没有被阻塞,他可以从其他用户处理查询
- 我们渲染视图
那么好code位置:
using System.Data.Entity;
public IQueryable<URL> GetAllUrls()
{
return context.Urls.AsQueryable();
}
public async Task<List<URL>> GetAllUrlsByUser(int userId) {
return await GetAllUrls().Where(u => u.User.Id == userId).ToListAsync();
}
请注意,不是必须添加为了使用方法
IQueryable的。 ToListAsync()
使用System.Data.Entity的
Note, than you must add using System.Data.Entity
in order to use method ToListAsync()
for IQueryable.
请注意,如果你并不需要筛选和分页之类的东西,你不需要用的IQueryable
工作。你可以只用等待context.Urls.ToListAsync()
和物化列表与LT工作; URL方式&gt;
Note, that if you don't need filtering and paging and stuff, you don't need to work with IQueryable
. You can just use await context.Urls.ToListAsync()
and work with materialized List<Url>
.
这篇关于实体框架可查询异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!