实体框架可查询异步 [英] Entity Framework Queryable async

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

问题描述

我正在使用实体框架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.


  1. 您不明白EF工作原理

  2. 您不知道如何异步/等待的作品。

那么,让我们来看看这个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?


  1. 我们越来越的IQueryable 对象使用(而不是访问数据库尚) repo.GetAllUrls()

  2. 我们创建一个使用。凡(U =&GT与指定的条件一个新的的IQueryable 对象;&lt;条件&GT;

  3. 我们创建指定分页限制使用新的的IQueryable 对象。取(10)

  4. 我们检索使用数据库结果 .ToList()。我们的的IQueryable 对象被编译为SQL(如选择顶部10 *从URL中其中&lt;条件&gt; )。和数据库可以使用索引,SQL服务器让你从你的数据库(而不是存储在数据库中的所有网址十亿)
  5. 只有10个对象
  1. We are getting IQueryable object (not accessing database yet) using repo.GetAllUrls()
  2. We create a new IQueryable object with specified condition using .Where(u => <condition>
  3. We create a new IQueryable object with specified paging limit using .Take(10)
  4. We retrieve results from database using .ToList(). Our IQueryable object is compiled to sql (like select 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:


  1. 我们使用的是加载在内存存储在数据库中的所有十亿网址等待context.Urls.ToListAsync();

  2. 我们得到了内存溢出。正确的方式杀死你的服务器

为什么异步/的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. 启动1号线 VAR stuff1 = ...

  2. 我们将请求发送到SQL Server,我们wan't得到一些stuff1为用户id

  3. 我们等待(当前线程被阻塞)

  4. 我们等待(当前线程被阻塞)

  5. ...

  6. SQL SERVER发送给我们回应

  7. 我们移动到2号线 VAR stuff2 = ...

  8. 我们将请求发送到SQL Server,我们wan't得到一些stuff2为用户id

  9. 我们等待(当前线程被阻塞)

  10. ,再次

  11. ...

  12. SQL SERVER发送给我们回应

  13. 我们渲染视图

因此​​,让我们来看看它的一个异步版本:

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?


  1. 我们将请求发送到SQL Server以获取stuff1(1号线)

  2. 我们将请求发送到SQL Server以获取stuff2(2号线)

  3. 我们等待从SQL Server响应,但当前线程没有被阻塞,他可以从其他用户处理查询

  4. 我们渲染视图

那么好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();
}

请注意,不是必须添加为了使用方法 ToListAsync()使用System.Data.Entity的 IQueryable的。

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屋!

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