迁移到 .NET8 后,F# 查询表达式和带有 Array.Contains 的 C# LINQ 失败

问题描述 投票:0回答:1

最近我已将代码迁移到 .NET8,但我的一些查询停止工作。 这是一个例子,它曾经在.NET7中工作

let accounts: Array[] = ...

query {
    for user in db.User do
      where accounts.Contains user.Account
      select user
  }

我收到错误:

Unhandled exception. System.InvalidOperationException: The LINQ expression 
'[Microsoft.EntityFrameworkCore.Query.InlineQueryRootExpression]' could not be translated. 
Additional information: Empty collections are not supported as inline query roots. Either 
rewrite the query in a form that can be translated, or switch to client evaluation 
explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 
'ToListAsync'.

我注意到现在表达式不喜欢空数组,并且当

accounts
不包含任何项目时它会失败。所以我需要在各处添加一个守卫,例如

let accounts: Array[] = ...

// This works just fine
query {
    for user in db.User do
      where (accounts.Length <> 0 && accounts.Contains user.Account)
      select user
  }

唯一的问题是,在我的代码库中,我多次使用

.Contains
方法。我真的需要在每个地方添加
accounts.Length <> 0 &&
部分吗?或者也许我可以做更好的事情?

我使用 SQL Server 2022。

c# sql f# .net-8.0 query-expressions
1个回答
1
投票

有一个与此相关的未决问题:Contains 是否停止在 EF Core 8 中的空列表上工作? #32375roji最小仓库

最小重现是在空内联数组之上进行任何组合:

_ = ctx.Blogs.Where(b => new int[] { }.Contains(b.Id)).ToList();

它已在 EF Core 主分支中修复,请参阅允许空内联集合 (#32414),但仍然存在于 RelationalQueryableMethodTranslatingExpressionVisitor.cs

8.0.0 分支中。
2023 年 11 月 30 日,该修复已批准包含在服务版本EF Core 8.0.2中。

因此,您可以等待 EF Core 8.0.2 服务版本,或者,如果您不能等待,请使用

accounts.Length <> 0 && ...
解决方法。

© www.soinside.com 2019 - 2024. All rights reserved.