最近我已将代码迁移到 .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。
有一个与此相关的未决问题:Contains 是否停止在 EF Core 8 中的空列表上工作? #32375 与 roji 的 最小仓库
最小重现是在空内联数组之上进行任何组合:
_ = ctx.Blogs.Where(b => new int[] { }.Contains(b.Id)).ToList();
它已在 EF Core 主分支中修复,请参阅允许空内联集合 (#32414),但仍然存在于 RelationalQueryableMethodTranslatingExpressionVisitor.cs
因此,您可以等待 EF Core 8.0.2 服务版本,或者,如果您不能等待,请使用
accounts.Length <> 0 && ...
解决方法。