通过分组依据

时间:2019-02-28 17:51:33

标签: c# linq entity-framework-core ef-core-2.2

考虑以下查询,该查询必须返回导演以及每部电影的电影和演员数。人们将如何使用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__AnonymousType8 1(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; }
}

1 个答案:

答案 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}};