我加入 .NetCore 3.1 抛出一个关于 NavigationExpandingExpressionVisitor 的异常,那是什么?
My join .NetCore 3.1 throws an exception about NavigationExpandingExpressionVisitor, what is that?
我有一个 .NetCore 3.1 项目。我知道从 EF Core 2 到 3 有重大变化,但寻找解决方案让我发现了一些毫无意义的地方。
以下适用于 .NetCore 2.2。
我有一个从其他查询生成的用户名列表。我现在想在我们的人事数据库中找到这些用户名,目的是返回每个用户名的关联电子邮件地址。一个人可以选择使用公司电子邮件地址或提供不同的地址。如果 person.EmailAddress
字段为空,那么我需要的地址是附加公司域的用户名。
private static List<string> GetEmailAddrsFromBp(PersonnelContext personnelContext, IEnumerable<string> userNames) {
try {
var personEmail = (
from person in personnelContext.Persons
join userName in userNames
on person.userName.Trim().ToLower() equals userName.Trim().ToLower()
where person.ActualEndDate == null
select person.EmailAddress.Trim().Equals("")
? person.userName.Trim().ToLower() + "@myCompany.com"
: person.EmailAddress.Trim().ToLower()
).Distinct().OrderBy(a => a).ToList();
return personEmail;
} catch (Exception e) {
throw new Exception("GetEmailAddrsFromBp: " + e.Message);
}
}
在 3.1 中我得到异常:
Processing of the LINQ expression 'DbSet<Persons>
.Join(
outer: __p_0,
inner: person => person.userName.Trim().ToLower(),
outerKeySelector: userName => userName.Trim().ToLower(),
innerKeySelector: (person, userName) => new {
person = person,
userName = userName
})' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
我不明白这个错误。转到建议的 Microsoft 站点没有帮助。其他谷歌搜索已证明无济于事。到底是怎么回事? "simple" 现在加入如何?
I do not understand this error.
错误信息当然不是用户友好的。唯一相关的部分是
This may indicate either a bug or a limitation in EF Core.
可以安全地读作 "This is either a bug or a limitation in EF Core."
What is going on? How do you do "simple" joins now?
您可以加入"simple",但不能加入内存集合。事实上,从未真正支持连接到内存集合。只是 EF Core 1.x / 2.x 使用所谓的 客户端评估 来处理它无法翻译的内容。但是 implicit client evaluation has been removed in 3.0,现在您应该找到一个可翻译的构造,或者通过 LINQ to Objects(或 System.Linq.Async
)显式切换到客户端评估。
由于专门针对连接切换到客户端评估效率不高,因此最好 find/use 可翻译的查询结构。如果你使用非equi或多键连接,你基本上没有选择。但是对于单键等值连接,有一个在所有 EF / EF Core 版本中都支持的结构,它是 Enumerable.Contains
转换为 SQL IN (val1, val2, ..., valN)
.
所以针对你的具体案例的解决方案是这样的:
userNames = userNames.Select(userName => userName.Trim().ToLower()).Distinct();
var personEmail = (
from person in personnelContext.Persons
where userNames.Contains(person.userName.Trim().ToLower())
// the rest of the query unchanged...
我有一个 .NetCore 3.1 项目。我知道从 EF Core 2 到 3 有重大变化,但寻找解决方案让我发现了一些毫无意义的地方。
以下适用于 .NetCore 2.2。
我有一个从其他查询生成的用户名列表。我现在想在我们的人事数据库中找到这些用户名,目的是返回每个用户名的关联电子邮件地址。一个人可以选择使用公司电子邮件地址或提供不同的地址。如果 person.EmailAddress
字段为空,那么我需要的地址是附加公司域的用户名。
private static List<string> GetEmailAddrsFromBp(PersonnelContext personnelContext, IEnumerable<string> userNames) {
try {
var personEmail = (
from person in personnelContext.Persons
join userName in userNames
on person.userName.Trim().ToLower() equals userName.Trim().ToLower()
where person.ActualEndDate == null
select person.EmailAddress.Trim().Equals("")
? person.userName.Trim().ToLower() + "@myCompany.com"
: person.EmailAddress.Trim().ToLower()
).Distinct().OrderBy(a => a).ToList();
return personEmail;
} catch (Exception e) {
throw new Exception("GetEmailAddrsFromBp: " + e.Message);
}
}
在 3.1 中我得到异常:
Processing of the LINQ expression 'DbSet<Persons>
.Join(
outer: __p_0,
inner: person => person.userName.Trim().ToLower(),
outerKeySelector: userName => userName.Trim().ToLower(),
innerKeySelector: (person, userName) => new {
person = person,
userName = userName
})' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
我不明白这个错误。转到建议的 Microsoft 站点没有帮助。其他谷歌搜索已证明无济于事。到底是怎么回事? "simple" 现在加入如何?
I do not understand this error.
错误信息当然不是用户友好的。唯一相关的部分是
This may indicate either a bug or a limitation in EF Core.
可以安全地读作 "This is either a bug or a limitation in EF Core."
What is going on? How do you do "simple" joins now?
您可以加入"simple",但不能加入内存集合。事实上,从未真正支持连接到内存集合。只是 EF Core 1.x / 2.x 使用所谓的 客户端评估 来处理它无法翻译的内容。但是 implicit client evaluation has been removed in 3.0,现在您应该找到一个可翻译的构造,或者通过 LINQ to Objects(或 System.Linq.Async
)显式切换到客户端评估。
由于专门针对连接切换到客户端评估效率不高,因此最好 find/use 可翻译的查询结构。如果你使用非equi或多键连接,你基本上没有选择。但是对于单键等值连接,有一个在所有 EF / EF Core 版本中都支持的结构,它是 Enumerable.Contains
转换为 SQL IN (val1, val2, ..., valN)
.
所以针对你的具体案例的解决方案是这样的:
userNames = userNames.Select(userName => userName.Trim().ToLower()).Distinct();
var personEmail = (
from person in personnelContext.Persons
where userNames.Contains(person.userName.Trim().ToLower())
// the rest of the query unchanged...