考虑以下查询,该查询必须返回导演以及每部电影的电影和演员数。人们将如何使用EF CORE 2.2在LINQ中编写此代码?我需要LINQ来生成实际上将GROUP BY与EF CORE 2.1及更高版本支持的SQL聚合一起使用的SQL。
SELECT DirectorName, COUNT(m.MovieID), COUNT(a.ActorID)
FROM Directors d
LEFT OUTER JOIN Movies AS m ON m.DirectorID = d.DirectorID
LEFT OUTER JOIN Actors AS a ON a.MovieID = m.MovieID
WHERE d.DirectorID = 1
GROUP BY DirectorName
样本LINQ查询是基于答案构建的,确实为我提供了结果,但该查询仅具有LEFT联接之一,而没有分组依据。输出表明DefaultIfEmpty(),GroupBy和Count无法转换,将在本地进行评估。
var results =
(
from d in _moviesContext.Directors
join m in _moviesContext.Movies on d.DirectorId equals m.DirectorId
into grpM from movies in grpM.DefaultIfEmpty()
join a in _moviesContext.Actors on movies.MovieId equals a.MovieId
into grpA from actors in grpA.DefaultIfEmpty()
where d.DirectorId == 1
group new { d, grpM, grpA } by new
{
d.DirectorName
} into grp
select new
{
DirectoryName = grp.Key.DirectorName,
MovieCount = grp.Sum(g => g.grpM.Count()),
ActorAcount = grp.Sum(g => g.grpA.Count())
}
).ToList();
LINQ表达式 'DefaultIfEmpty()'无法翻译,将被评估 本地。 Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式'DefaultIfEmpty()'无法翻译,将被 本地评估。 Microsoft.EntityFrameworkCore.Query:警告: LINQ表达式“来自{[grpM] => DefaultIfEmpty()}中的电影电影” 无法翻译,将在本地进行评估。 Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 'GroupBy(new <> f__AnonymousType8
1(DirectorName = [d].DirectorName), new <>f__AnonymousType6
2(d = [d],grpM = [grpM]))' 翻译,并将在本地进行评估。 Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 'DefaultIfEmpty()'无法翻译,将被评估 本地。 Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式'DefaultIfEmpty()'无法翻译,将被 本地评估。 Microsoft.EntityFrameworkCore.Query:警告: LINQ表达式“来自{[grpM] => DefaultIfEmpty()}中的电影电影” 无法翻译,将在本地进行评估。 Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 'GroupBy(new <> f__AnonymousType81(DirectorName = [d].DirectorName), new <>f__AnonymousType6
2(d = [d],grpM = [grpM]))' 翻译,并将在本地进行评估。 Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 'Count()'无法翻译,将在本地进行评估。 Microsoft.EntityFrameworkCore.Query:警告:LINQ表达式 “ Sum()”无法翻译,将在本地进行评估。
这是模特
public partial class Directors
{
public int DirectorId { get; set; }
public string DirectorName { get; set; }
}
public partial class Movies
{
public int MovieId { get; set; }
public string MovieName { get; set; }
public int? DirectorId { get; set; }
}
public partial class Actors
{
public int ActorId { get; set; }
public string ActorName { get; set; }
public int? MovieId { get; set; }
}
答案 0 :(得分:0)
我不确定为什么当演员通常具有电影列表时,您的演员为什么只有电影ID的整数,但是我认为您需要在组中包括所有三种对象类型,然后选择不同的电影和演员来得到计数。
示例:
var directors = new[] { new { DirectorName = "Director A", DirectorID = 1 },
new { DirectorName = "Director B", DirectorID = 2 }};
var movies = new[] { new { MovieName = "Movie A", MovieID = 1, DirectorID = 1 },
new { MovieName = "Movie B", MovieID = 2, DirectorID = 2 }};
var actors = new[] { new { ActorName = "Actor A", ActorID = 1, MovieID = 1},
new { ActorName = "Actor B", ActorID = 2, MovieID = 1},
new { ActorName = "Actor C", ActorID = 3, MovieID = 1},
new { ActorName = "Actor D", ActorID = 4, MovieID = 2}};
var results = from d in directors
from m in movies
.Where(m => m.DirectorID == d.DirectorID)
from a in actors
.Where(a => a.MovieID == m.MovieID)
where d.DirectorID == 1
group new { d, m, a } by d.DirectorName into grp
select new
{ DirectorName = grp.Key,
MovieCount = grp.Select(x => x.m).Distinct().Count(),
ActorCount = grp.Select(x => x.a).Distinct().Count()
};
会产量
result = new [] { new { DirectorName = "Director A", MovieCount = 1, ActorCount = 3}};