【问题标题】:Using Any() inside Where () in EF Core 3.1在 EF Core 3.1 的 Where () 中使用 Any()
【发布时间】:2020-04-07 14:28:37
【问题描述】:
await this.dbContext
          .UserTeams
          .Where(ut =>
                   teamMembers.Any(tm => tm.UserId == ut.UserId 
                                         && ut.TeamId == tm.TeamId))
          .ToListAsync();

这里的 teamMember 是一个简单的列表,其中包含分组的 UserIdsTeamIds。如果我使用 Contains()UserIdTeamId 是这里的复合键,这将有效。

这是一个相当简单的查询,无法翻译。

错误:

System.InvalidOperationException: The LINQ expression 'DbSet<UserTeam>
     .Where(u => __teamMembers_0
         .Any(tm => u.TeamId == tm.TeamId && u.UserId == tm.UserId))' 
could not be translated. 
Either rewrite the query in a form that can
be translated, or switch to client evaluation explicitly by inserting
a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync()

【问题讨论】:

  • teamMembers 是什么?
  • 这从未奏效(EF 或 EF Core),主要是因为没有这样的 SQL 构造(IN 不支持复合值)。
  • SP 无济于事,除非你能通过 TVP。有关不同选项,请参阅此答案 stackoverflow.com/questions/26198860/…。它适用于 EF6,但同样适用于 EF Core。
  • @MujahidDaudKhan TVP 代表表值参数,而不是元组。
  • 一种选择是将这对 Guid 值转换为字符串表示形式,然后对其进行搜索。不利的一面是您将无法利用这些列上的任何索引。如果您的桌子不是很大,这可能是一个可行的选择。

标签: c# linq ef-core-3.1


【解决方案1】:

问题是 EF 不能翻译复杂的对象。 EF 只能在 SQL 参数中翻译 .NET 内存对象,并在 SQL 查询中使用这些 SQL 参数。

我看到了一个可行的选项。由于除了使用组合值进行简单查找之外,您没有做任何特定的事情,您可以尝试在单个 SQL 参数中转换用户 ID/团队 ID 组合。例如,值为“-”的字符串。我假设你的 id 是简单的整数。如果它们是字符串,则可能需要使用不同的分隔符。使用该组合值在您的数据库源中查找任何匹配项。

以下代码未经测试,可能无法正常工作。另一种方法是创建某种视图以在数据库端创建组合值。

    var memberIds = teamMembers.Select(tm => $"{tm.UserId}-{tm.TeamId}").ToArray();
    await this.dbContext
              .UserTeams
              .Where(ut => memberIds.Contains(
                               SqlFunctions.StringConvert((double?)tm.UserId) + "-" +
                               SqlFunctions.StringConvert((double?)tm.TeamId)
                           )
                    )
              .ToListAsync();

【讨论】:

  • 似乎是个好主意。如果我们真的想要索引,我们可以创建一个已经包含计算键对的列,而不是在运行时为每个查询评估它。然后我们可以在具有只读属性的域类中使用这个逻辑,或者使用触发器在这个列中自动插入这个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 2022-11-11
  • 1970-01-01
  • 2021-04-22
相关资源
最近更新 更多