我完全陷入了这个简单的查询,它是用 Entity Framework Core 6 制作的,它应该返回一个问题列表,计算每个问题的答案数量(就像一个论坛......):
questions = from q in context.ExpertsForumQuestions
join a in context.ExpertsForumAnswers on q.ExpertsForumQuestionId equals a.ExpertsForumQuestionId into ja
from a in ja.DefaultIfEmpty()
join ui in context.UserInfos on q.UserInfoId equals ui.UserInfoId
where q.Languageid == languageId
group q by new { q, ui } into g
select new QuestionListItem
{
ExpertsForumQuestionId = g.Key.q.ExpertsForumQuestionId,
Title = g.Key.q.Title,
FirstNameSubmitter = g.Key.ui.FirstName,
LastNameSubmitter = g.Key.ui.LastName,
Categories = g.Key.q.Categories,
NumberOfAnswers = g.Count()
};
EF Core 无法翻译它,返回此错误消息:
LINQ 表达式 'DbSet()
.LeftJoin(
内部:DbSet(),
外键选择器:e => e.ExpertsForumQuestionId,
内部KeySelector:e0 => e0.ExpertsForumQuestionId,
结果选择器:(e,e0)=>新的透明标识符(
外= e,
内 = e0
))
.加入(
内部:DbSet(),
外键选择器:ti => ti.Outer.UserInfoId,
内部KeySelector:u => u.UserInfoId,
结果选择器:(ti,u)=>新的透明标识符,用户信息>(
外=ti,
内=u
))
.GroupBy(ti0 => 新 {
q = ti0.Outer.Outer,
ui = ti0.Inner
})' 无法翻译。以可翻译的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端计算。请参阅 https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。
为什么翻译不了?
我希望它不属于此处报告的问题范围 https://github.com/dotnet/efcore/issues/19813
否则,EF Core 的朋友们……我们仍处于该产品的 alpha 版本!
我认为这是GroupBy和select和evaluation的问题。 GroupBy 强制它进行评估。您会在 GroupBy 之后直接看到错误。
因此,通过不使用 select 而是直接在 GroupBy 中创建 QuestionListItem 可以避免选择。我从 2.1 迁移到 5 时遇到了这个问题。也许这对你来说也是一样的。
试试这个(它在 LinqPad 中有效):
var questions2 = expertsForumQuestions
.GroupJoin(
expertsForumAnswers,
q => q.ExpertsForumQuestionId,
a => a.ExpertsForumQuestionId,
(q, ja) => new { q, ja })
.SelectMany(
x => x.ja.DefaultIfEmpty(),
(x, a) => new { x.q, a })
.Join(
userInfos,
x => x.q.UserInfoId,
ui => ui.UserInfoId,
(x, ui) => new { x.q, ui })
.GroupBy(
x => new { x.q, ui = x.ui },
(key, g) => new QuestionListItem
{
ExpertsForumQuestionId = key.q.ExpertsForumQuestionId,
Title = key.q.Title,
FirstNameSubmitter = key.ui.FirstName,
LastNameSubmitter = key.ui.LastName,
Categories = key.q.Categories,
NumberOfAnswers = g.Count()
});
questions2.Dump();