Repository navigation
Aggregate function on owned type fails in EF8 #36990
Copy link
Copy link
Description
Bug description
Code below works in EF Core 6.0. But failed on EF Core 8.0.
I found the same issue #29201, but it was closed. The solution that was proposed only works with the Sum method.
Your code
using Microsoft.EntityFrameworkCore;
namespace GroupOwnedFields;
[Owned]
public class Period
{
public DateTime Begin { get; set; }
public DateTime End { get; set; }
}
public class Point
{
public int Id { get; set; }
public int OwnerId { get; set; }
public DateTime DateTime { get; set; }
public required Period Period { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Point> Points { get; set; }
public AppDbContext()
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=localhost;Initial Catalog=Test;Persist Security Info=True;User ID=test;Password=test");
optionsBuilder.EnableSensitiveDataLogging();
}
}
public class Program
{
public static void Main(string[] args)
{
using var context = new AppDbContext();
var query = context.Points
.GroupBy(e => e.OwnerId)
.Select(g => new
{
TotalCount = g.Count(),
PastCount = g.Count(e => e.Period.End < DateTime.UtcNow)
});
var queryText = query.ToQueryString();
}
}Stack traces
System.InvalidOperationException
HResult=0x80131509
Message=Translation of 'EF.Property<Period>(StructuralTypeShaperExpression:
GroupOwnedFields.Point
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Period")' failed. Either the query source is not an entity type, or the specified property does not exist on the entity type.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMember(MemberExpression memberExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.ProcessPredicate(EnumerableExpression enumerableExpression, LambdaExpression lambdaExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TryTranslateAggregateMethodCall(MethodCallExpression methodCallExpression, SqlExpression& translation)
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.TryTranslateAggregateMethodCall(MethodCallExpression methodCallExpression, SqlExpression& translation)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)
at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateProjection(Expression expression, Boolean applyDefaultTypeMapping)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitNew(NewExpression newExpression)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToQueryString(IQueryable source)
at GroupOwnedFields.Program.Main(String[] args) in D:\Projects\Git\GroupOwnedFields\GroupOwnedFields\Program.cs:line 52
Verbose output
EF Core version
8.0.21
Database provider
No response
Target framework
.NET 8.0
Operating system
No response
IDE
No response
Reactions are currently unavailable
Activity
cincuranet commentedon Oct 17, 2025
Repros on
mainas well.QHarshil commentedon Sep 3, 2026
The binding failure comes from aggregate lambdas over a grouping being remapped onto the grouping element in
RelationalSqlTranslatingExpressionVisitor, which doesn't expand owned navigations, so the navigation never binds. #29201 made that non-fatal for aggregate selectors, which then fall back to a correlated subquery per aggregate;Countwith a predicate goes throughProcessPredicateand still throws.I have a fix that runs the existing shared-type entity expansion over the remapped lambda body. It also covers #37778, #29593 and #31062, which have the same cause. I can open a PR if that approach looks right.
QHarshil commentedon Sep 4, 2026
Implementation and regression tests are on my fork: https://github.com/QHarshil/efcore/tree/query/owned-navigations-in-groupby-aggregates
The change expands owned navigations on the lambda after it is remapped onto the grouping element in
RelationalSqlTranslatingExpressionVisitor, reusing the expansion the queryable translator already runs elsewhere. A dependent mapped to its own table is left unexpanded, since expanding it would add an owner join and the dependent's key as an identifier to a query that has already been grouped; those queries keep the translation they have today.It covers #36990, #37778, #29593 and #31062: JSON-mapped, table-splitting and entity-splitting owned types, owned types nested in those, owned collections, aggregate selectors,
Countpredicates,Whereover the grouping, and orderings.One design question before I open a PR. #38668 handled reference navigations by lifting into pre-GroupBy joins in navigation expansion; this does the owned case in the relational translator, after grouping is applied. Is that the layer you want it in? I would rather move it now than after review.
Query: expand owned navigations in GroupBy aggregate selectors
Query: expand owned navigations in GroupBy aggregate selectors
Query: expand owned navigations in GroupBy aggregate selectors (dotne…
Query: expand owned navigations in GroupBy aggregate selectors (#38918)