C#连接列表。LINQ。无法创建常量类型。

3

想象以下的方法。

public async Task<IHttpActionResult> Get(int id)
    {

        List<PageVirtualServer> pageVirtualServer = await context.PageVirtualServer
              .Where(z => z.StatusPageId == id)
              .ToListAsync();


        List<StatusMessage> messages = await context.StatusMessages
              .Where(x => pageVirtualServer.Any(
                         y => y.VirtualServerId == x.VirtualServerId))
              .ToListAsync();

        return  Ok(messages);
    }

以下异常会发生: "无法创建类型为'xy'的常量值。只支持原始类型或枚举类型在此上下文中使用。"
但是当将第一个查询嵌入到第二个查询中时,它确实可以工作, 我不理解。
为什么这种方法有效而第一个方法无效?
public async Task<IHttpActionResult> Get(int id)
    {

        List<StatusMessage> messages = await context.StatusMessages
             .Where(x => 
                context.PageVirtualServer
                   .Where(z => z.StatusPageId == id)
                   .Any(y => y.VirtualServerId == x.VirtualServerId))
             .ToListAsync();

        return  Ok(messages);
}

能有人解释一下这种行为吗?

ToListAsync 返回的是 Task<List<object>>,而不是 List<object>。你需要解开 result - AD.Net
即使没有使用async和await,EF也会抛出“notsupportedexception”异常 :( - Erik Mandke
1个回答

5
在你的第一个示例中,你在内存中实例化了一个PageVirtualServer对象列表,并将该对象列表传递给第二个查询。Linq to Entities无法将其转换为SQL语句。
在第二个查询中,你基本上告诉EF使用表context.PageVirtualServer,从而使EF生成一个SQL查询以一次性执行整个操作。
要分两步执行此操作,你可以在第一个查询中实例化ID:
        List<int> pageVirtualServerIDs = await context.PageVirtualServer
              .Where(z => z.StatusPageId == id)
              .Select(z => z.Id)
              .ToListAsync();


        List<StatusMessage> messages = await context.StatusMessages
              .Where(x => pageVirtualServerIDs.Contains(x.VirtualServerId))
              .ToListAsync();

然而,我强烈推荐坚持使用一次查询。我认为写作时更合理的方式是:

    List<StatusMessage> messages = await (
          from statusMessage in context.StatusMessages
          join pvs in context.PageVirtualServer 
          on statusMessage.VirtualServerId = pvs.VirtualServerId
          where pvs.StatusPageId == id
          select statusMessage
    ).ToListAsync();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接