【问题标题】:entity.ToListAsync().Where or entity.Where()?entity.ToListAsync().Where 还是 entity.Where()?
【发布时间】:2018-05-28 15:41:02
【问题描述】:

我无法确定哪种方式最适合在我的 WebAPI 2 后端查询我的 SQL Server

我尝试尽可能频繁地使用 async/await,但我发现当我返回整个集合时,没有可用的异步选项。

哪种方式最好?

[ResponseType(typeof(List<ExposedPublisher>))]
[HttpGet]
public async Task<IHttpActionResult> GetPublisher()
{
    var list = new List<PublisherWithMedia>();
    foreach (var publisher in _db.Publisher.Where(e => e.IsDeleted == false))
    {
        var pub = new PublisherWithMedia()
            {
                Id = publisher.Id,
                Name = publisher.Name,
                Mediae = new List<WebClient.Models.Media>()
            };
            foreach (var media in publisher.Media)
            {
                pub.Mediae.Add(ApiUtils.GetMedia(media));
            }
        list.Add(pub);
    }
    return Ok(list);
}

[ResponseType(typeof(List<PublisherWithMedia>))]
[HttpGet]
public async Task<IHttpActionResult> GetPublisher()
{
    var list = new List<PublisherWithMedia>();
    var entity = await _db.Publisher.ToListAsync();
    foreach (var publisher in entity.Where(e => e.IsDeleted == false))
    {
        var pub = new PublisherWithMedia()
            {
                Id = publisher.Id,
                Name = publisher.Name,
                Mediae = new List<WebClient.Models.Media>()
            };
            foreach (var media in publisher.Media)
            {
                pub.Mediae.Add(ApiUtils.GetMedia(media));
            }
        list.Add(pub);
    }
    return Ok(list);
}

该操作可能会导致非常大的结果集,因此直接在数据库上进行过滤是有意义的,特别是随着时间的推移,已删除记录的数量可能会超过未删除记录的数量。 但是,对于较大的结果和子(媒体)的查询,让操作异步工作也是有意义的,因为它应该相当耗时。 可悲的是,在这种情况下没有异步 Where()

或者有没有我不知道的第三种方式?

【问题讨论】:

  • 目前不会为Media中的每个项目调用数据库吗?

标签: c# asp.net-web-api async-await entity-framework-6


【解决方案1】:

您可以两全其美:在数据库中过滤并异步执行查询:

var publishers = await _db.Publisher
    .Where(e => !e.IsDeleted)
    .ToListAsync();

也就是说,根据 ApiUtils.GetMedia(media) 所做的事情,您甚至可以对查询执行投影:

var publishers = await _db.Publisher
    .Where(e => !e.IsDeleted)
    .Select(e => new PublisherWithMedia()
    {
        Id = e.Id,
        Name = e.Name,
        Mediae = e.Mediae.Select(m => ApiUtils.GetMedia(m)).ToList()
    };
    .ToListAsync();

【讨论】:

  • 在这种情况下Where() 的结果是IQueryable,它不提供任何异步操作。
  • @Kyte 您可能缺少using 语句(我相信是System.Data.Entity),因为ToListAsync()IQueryable&lt;T&gt; 上的扩展方法
  • @CamiloTerevinto 是的,你是对的。我现在觉得很愚蠢,因为我一次又一次地偶然发现这个问题,即使经过数小时的研究我也找不到答案,只能解释为什么由于各种原因不可能。
  • @Kyte 别担心,我们所有人都曾有过这样的经历
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
相关资源
最近更新 更多