Search code examples
c#entity-frameworkef-core-3.0

EF Core LINQ query failing due to limitation?


I am trying to do quite a simple group by, and sum, with EF Core 3.0

However am getting a strange error:

System.InvalidOperationException: 'Processing of the LINQ expression 'AsQueryable((Unhandled parameter: y).TransactionLines)' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core.

 var creditBalances = await context.Transaction
                .Include(x => x.TransactionLines)
                .Include(x=>x.CreditAccount)
                .Where(x => x.CreditAccount.UserAccount.Id == userAccount.Id)
                .GroupBy(x => new
                {
                    x.CreditAccount.ExternalId
                })
                .Select(x => new
                {
                    x.Key.ExternalId,
                    amount = x.Sum(y => y.TransactionLines.Sum(z => z.Amount))
                })
                .ToListAsync();

I'm battling to see where an issue can arise, so not even sure where to start. I am trying to get a sum of all the transaction amounts (Which is a Sum of all the TransactionLines for each transaction - i.e. A Transaction amount is made of the lines associated to it).

I then sum up all the transactions, grouping by then CreditAccount ID.

The line, Unhandled parameter: y is worrying. Maybe my grouping and summing is out.


Solution

  • So start at the TransactionLines level and this is as simple as:

    var q = from c in context.TransactionLines
            where c.Transaction.CreditAccount.UserAccount.Id == userAccount.Id
            group c by c.Transaction.CreditAccount.ExternalId into g
            select new
            {
                ExternalId = g.Key,
                Amount = g.Sum(x => x.Amount)
            };
    
    var creditBalances = await q.ToListAsync();
    

    ( You don't need any Include() since you're not returning an Entity with related data. You're projecting a custom data shape. )

    Which translates to:

    SELECT [c].[ExternalId], SUM([t].[Amount]) AS [Amount]
    FROM [TransactionLines] AS [t]
    LEFT JOIN [Transaction] AS [t0] ON [t].[TransactionId] = [t0].[Id]
    LEFT JOIN [CreditAccounts] AS [c] ON [t0].[CreditAccountId] = [c].[Id]
    LEFT JOIN [UserAccount] AS [u] ON [c].[UserAccountId] = [u].[Id]
    WHERE [u].[Id] = @__userAccount_Id_0
    GROUP BY [c].[ExternalId]