EF Core - как группировать по столбцу, допускающему значение NULL, с помощью нескольких объединений

Учитывая следующие модели в EF Core 2.2:

public class A
{
    public int Id { get; set; }
    public ICollection<B> Bs { get; set; }
}

public class B
{
    public int Id { get; set; }
    public int AId { get; set; }
    public ICollection<C> Cs { get; set; }
}

public class C
{
    public int Id { get; set; }
    public int BId { get; set; }
    public long? DId { get; set; }
}

public class D
{
    public long Id { get; set; }
}

Я хочу выполнить этот запрос:

from a in context.Set<A>()
from b in a.Bs
from c in b.Cs
where c.DId.HasValue
group c by c.DId.Value into g
select new
{
    g.Key,
    Count = g.Count() - 1
}

Но когда я пытаюсь выполнить это, я получаю:

Выражение LINQ "GroupBy(Convert([b.Cs].DId, Int64), [b.Cs])" не может быть переведено и будет вычислено локально.

Я сослался на это:

Но я не могу правильно составить запрос. Возможно ли это в EF Core 2.2? Или есть лучший способ получить желаемый результат?


person crgolden    schedule 28.12.2019    source источник


Ответы (1)


Нет ничего плохого в том, как вы составляете запрос. Это всего лишь одна из ошибок / дефектов трансляции запросов EF Core 2.2, потому что group by c.DId работает, но результирующий тип ключа long?. Также в EF Core 3.1 запрос переводится правильно.

Обходной путь для 2.2 - использовать промежуточный анонимный тип для ключа группировки, при котором вы выполняете «преобразование», допускающее значение NULL, в не допускающее значение NULL. Что-то вроде этого:

group c by new { Value = c.DId.Value } into g
select new
{
    Key = g.Key.Value,
    Count = g.Count() - 1
}
person Ivan Stoev    schedule 28.12.2019