实体框架ToListAsync()与Select()

Sub*_*ive 5 c# linq asp.net-mvc entity-framework

我的控制器中有以下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());
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的是运行此异步,但是如果在方法变得不可用ToListAsync()之前添加.同样适用于.Select()Select()return PartialView(tickets.ToList())

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

任何帮助我发送正确方向的人都将不胜感激!

Han*_*ing 8

分为两个陈述:

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

var tickets = tickets0.Select(...);
Run Code Online (Sandbox Code Playgroud)

.ToListAsync()回报Task,所以它不接受.Select扩展方法,这将需要一些IEnumerable.只有你await那个任务,你才会得到List.

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

 var tickets = (await (from ...).ToListAsync()).Select(...);
Run Code Online (Sandbox Code Playgroud)

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

  • 这可能有效,但它会将表查询中的每一列作为 toList 的结果带回内存,然后在那里进行投影,而不是仅带回投影的列。 (3认同)

Nko*_*osi 5

您将需要在调用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);
}
Run Code Online (Sandbox Code Playgroud)