实体框架ToListAsync()与Select()

时间:2017-07-06 11:25:09

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

我的控制器中有以下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()之前添加Select() Select()方法变得不可用。 return PartialView(tickets.ToList())也是如此。

我很擅长使用异步,但是阅读它的优点我已经将常规ActionResult方法与异步方法进行了融合。到目前为止,基于LINQ的查询更加简单。但是对于这个ActionResult方法,查询更高级,实现它的语法/方式似乎有所不同。

非常感谢任何向我发送正确方向的帮助!

3 个答案:

答案 0 :(得分:8)

分成两个陈述:

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

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

.ToListAsync()会返回Task,因此它不接受.Select扩展方法,该方法需要一些IEnumerable。只有当您await该任务时,您才能获得List

另一种方式(不太可读的IMO)将是:

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

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

答案 1 :(得分:4)

在调用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);
}

答案 2 :(得分:2)

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