【问题标题】:C# joined lists. LINQ. unable to create a constant typeC# 加入列表。 LINQ。无法创建常量类型
【发布时间】:2015-11-08 19:13:27
【问题描述】:

想象以下方法。

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&lt;List&lt;object&gt;&gt;,而不是List&lt;object&gt;?您必须打开 result
  • 即使没有异步和等待。 EF 给我一个“不支持的异常”:(

标签: c# entity-framework linq asynchronous


【解决方案1】:

在您的第一个示例中,您在内存中实现了 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();

但是,我强烈希望坚持一个查询。写这个稍微更合乎逻辑的方式(IMO)是这样的:

    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();

【讨论】:

    猜你喜欢
    • 2013-06-08
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多