【问题标题】:Entity Framework ToListAsync() with Select()实体框架 ToListAsync() 与 Select()
【发布时间】:2019-01-12 00:34:52
【问题描述】:

我的控制器中有以下 ActionResult

public async Task<ActionResult> NewTickets()
{
    // Show tickets for all divisions a agent is in

    var user = "abcdefg";
    var company = "company1";

    var tickets = (from a in db2.Ticket
        join c in db2.Division on a.DivisionId equals c.DivisionId
        join dp in db2.DivisionParticipator on c.DivisionId equals dp.DivisionId
        where c.CompanyId == company.CompanyId && a.Status == "New" && dp.ApplicationUserId == user.Id
        select new
        {
            Id = a.Id,
            DivisionId = a.DivisionId,
            Name = a.Name,
            TicketDate = a.TicketDate,
            NewPosts = a.NewPosts,
            Status = a.Status,
            Type = a.Type
         })
         .ToList().Select(x => new Ticket
         {
             Id = x.Id,
             DivisionId = x.DivisionId,
             Name = x.Name,
             TicketDate = x.TicketDate,
             NewPosts = x.NewPosts,
             Status = x.Status,
             Type = x.Type
          });            

    return PartialView(tickets.ToList());
}

我想要实现的是运行这个异步,但是如果添加ToListAsync()before Select()Select() 方法将变得不可用。 return PartialView(tickets.ToList()) 也是如此。

我对使用 async 还很陌生,但阅读了它的优势,我一直在将常规 ActionResult 方法与 async 方法转换。到目前为止,使用更简单的基于 LINQ 的查询进展顺利。然而,对于这个 ActionResult 方法,查询更高级一些,实现它的语法/方式似乎有所不同。

任何帮助我朝正确的方向前进将不胜感激!

【问题讨论】:

  • ToListAsync 将返回一个Task,而不是List,所以你不能Select 覆盖它——你必须await ... .ToListAsync() 然后选择它...不过,我确实想知道你为什么在那个时候ToListing。
  • 您能否解释一下为什么在查询过程中需要ToList?通常ToList、ToArray在查询结束时调用以保存枚举结果

标签: c# asp.net-mvc entity-framework linq


【解决方案1】:

分成两个语句:

var tickets0 = await (from ...).ToListAsync();

var tickets = tickets0.Select(...);

.ToListAsync() 返回一个Task,因此它不接受.Select 扩展方法,这需要一些IEnumerable。只有当你await那个Task时,你才会得到List。

另一种方式(IMO 可读性较差)是:

 var tickets = (await (from ...).ToListAsync()).Select(...);

注意 await 子句周围的额外 ( ),这意味着 Select 将处理等待代码的结果,而不是 Task。

【讨论】:

  • 这个,连同@Ant P 所建议的,它工作得完美无缺!谢谢!
  • 这可能有效,但它会将表查询中的每一列作为 toList 的结果带回内存,然后在那里进行投影,而不是只带回投影的列。
【解决方案2】:

您需要在调用 select 之前等待查询,但鉴于查询只是从查询中选择模型,您可以在查询中创建模型并等待。

public async Task<ActionResult> NewTickets()
{
    // Show tickets for all divisions a agent is in

    var user = "abcdefg";
    var company = "company1";

    var tickets = await (from a in db2.Ticket
        join c in db2.Division on a.DivisionId equals c.DivisionId
        join dp in db2.DivisionParticipator on c.DivisionId equals dp.DivisionId
        where c.CompanyId == company.CompanyId && a.Status == "New" && dp.ApplicationUserId == user.Id
        select new Ticket
        {
            Id = a.Id,
            DivisionId = a.DivisionId,
            Name = a.Name,
            TicketDate = a.TicketDate,
            NewPosts = a.NewPosts,
            Status = a.Status,
            Type = a.Type
         })
         .ToListAsync();

    return PartialView(tickets);
}

【讨论】:

    【解决方案3】:

    您还需要导入System.Data.Entity 而不仅仅是System.Linq。这可能看起来很愚蠢,但由于这个原因,我最终提出了这个问题。 ToList 是 Linq 的一部分,但异步方法特定于 EF。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-08
      • 1970-01-01
      • 2020-11-09
      • 2022-01-22
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      • 2013-08-10
      相关资源
      最近更新 更多