无法在 EF Core 5/6 中的子选择上使用 GroupBy

时间:2021-04-30 08:18:09

标签: c# .net entity-framework group-by

我目前正在尝试使用 Entity Framework Core 5(也测试了 6)为客户实现报告,但遇到了一个我无法解决的问题。

我正在尝试查询所有客户/银行账户的列表,以及他们每月的总销售额。 因此,我尝试将符合条件的所有客户预订按月分组并汇总其金额。

应该不是那么难的任务。

这是我的查询:

context.Kontens
            .Select(k => new
            {
                Creditor = context.DebitorKreditors
                    .Include(k => k.Kontakt)
                    .FirstOrDefault(d => d.Nr == k.KtoNr),

                Sums = k.BuchZeilenKtos
                    .Where(b => b.Buch.Belegdatum.Year == DateTime.Now.Year
                        && (
                            (b.GegenKto.KtoNr >= xxxxxx && b.GegenKto.KtoNr <= xxxxxx)
                            || (b.GegenKto.KtoNr >= xxxxxx && b.GegenKto.KtoNr <= xxxxxx)
                            || (b.GegenKto.KtoNr >= xxxxxx && b.GegenKto.KtoNr <= xxxxxx)
                            )
                        )
                    .GroupBy(b => b.Buch.Belegdatum.Month)
                    .Select(g => new
                    {
                        Sum = g.Sum(b => b.Betrag * (b.SollHaben == "-" || b.SollHaben == "H" ? -1 : 1)),
                        Month = g.Key
                    }),

                Sum334 = k.BuchZeilenKtos
                    .Where(b => b.GegenKto.KtoNr >= xxxxxx && b.GegenKto.KtoNr <= xxxxxx)
                    .Sum(b => b.Betrag * (b.SollHaben == "-" || b.SollHaben == "H" ? -1 : 1))
            })
            .Where(k => k.Creditor.Kreditor && k.Sums.Any())
            .OrderBy(k => k.Creditor.Nr)
            .ToList()

翻译:

BuchzeilenKtos = Bookings
Kontens = Bank Accounts
DebitorKreditors = Customers
Buch = Booking

The bank account numbers have been removed due to privacy reasons.

有了这个,我收到以下错误,抱怨缺少关键列:

System.InvalidOperationException: Unable to translate collection subquery in projection since it uses 'Distinct' or 'Group By' operations and doesn't project key columns of all of it's tables which are required to generate results on client side. Missing column: b.ID. Either add column(s) to the projection or rewrite query to not use 'GroupBy'/'Distinct' operation.

我尝试了很多方法,包括将 GroupBy 更改为还包含关键列:

                    .GroupBy(b => new
                    {
                        b.Buch.Belegdatum.Month,
                        b.Id,
                        b.GegenKto,
                        b
                    })

但是根据我对 LINQ 分组的理解,这应该会产生错误的结果。

尽管如此,现在 EF 抱怨无法翻译查询并希望我更改为客户端处理,由于处理的预订量非常大,这不是一个选项:

System.InvalidOperationException: The LINQ expression 'DbSet<BuchZeilen>()
.Where(b => EF.Property<Nullable<Guid>>(EntityShaperExpression:
    EntityType: Konten
    ValueBufferExpression:
        ProjectionBindingExpression: EmptyProjectionMember
    IsNullable: False
, "Id") != null && object.Equals(
    objA: (object)EF.Property<Nullable<Guid>>(EntityShaperExpression:
        EntityType: Konten
        ValueBufferExpression:
            ProjectionBindingExpression: EmptyProjectionMember
        IsNullable: False
    , "Id"),
    objB: (object)EF.Property<Nullable<Guid>>(b, "KtoId")))
.Join(
    inner: DbSet<Buchung>(),
    outerKeySelector: b => EF.Property<Nullable<Guid>>(b, "BuchId"),
    innerKeySelector: b0 => EF.Property<Nullable<Guid>>(b0, "Id"),
    resultSelector: (o, i) => new TransparentIdentifier<BuchZeilen, Buchung>(
        Outer = o,
        Inner = i
    ))
.LeftJoin(
    inner: DbSet<Konten>(),
    outerKeySelector: b => EF.Property<Nullable<Guid>>(b.Outer, "GegenKtoId"),
    innerKeySelector: k0 => EF.Property<Nullable<Guid>>(k0, "Id"),
    resultSelector: (o, i) => new TransparentIdentifier<TransparentIdentifier<BuchZeilen, Buchung>, Konten>(
        Outer = o,
        Inner = i
    ))
.Where(b => b.Outer.Inner.Belegdatum.Year == DateTime.Now.Year && b.Inner.KtoNr >= 311000 && b.Inner.KtoNr <= 319999 || b.Inner.KtoNr >= 334000 && b.Inner.KtoNr <= 334999 || b.Inner.KtoNr >= 340000 && b.Inner.KtoNr <= 340999)
.GroupBy(
    keySelector: b => new {
        Month = b.Outer.Inner.Belegdatum.Month,
        Id = b.Outer.Outer.Id,
        GegenKto = b.Inner,
        b = b.Outer.Outer
     },
    elementSelector: b => b.Outer.Outer)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'.

我已经读过,EF Core 5 已经删除了 GroupBy/Distinct 上相关子查询的某些功能,但我不确定这是否是我的确切情况。在我看来,查询不应该太具体,EF 无法处理。

有谁知道我如何才能实现、我正在尝试做什么或者至少是否有可能?

0 个答案:

没有答案