I created a model where I have OwnsMany property used on 2 levels. Code sample below
```using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace EFProjectionRepro
{
public class Context : DbContext
{
public DbSet
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer("Server=localhost,1433;User Id=sa;Password=Password1!");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Entity>(cfg =>
{
cfg.OwnsMany(e => e.Children, inner =>
{
inner.OwnsMany(e => e.Owned);
});
});
}
}
public class Entity
{
public int Id { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int Type { get; set; }
public List<Owned> Owned { get; set; }
}
public class Owned
{
public string Value { get; set; }
}
}
```using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace EFProjectionRepro
{
class Program
{
static async Task Main(string[] args)
{
using var dbContext = new Context();
dbContext.Entities.Add(new Entity());
await dbContext.SaveChangesAsync();
await dbContext.Entities.ToListAsync();
}
}
}
When running saving Entity works, but when trying to read Entity from sql database (await dbContext.Entities.ToListAsync();) I get exception:
```Unhandled exception. System.InvalidOperationException: The LINQ expression 'ShapedQueryExpression:
QueryExpression:
Projection Mapping:
EmptyProjectionMember -> [EntityProjectionExpression]
SELECT 1
FROM Owned AS o
ShaperExpression: EntityShaperExpression:
EntityType: Owned
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
.Where(namelessParameter{0} => new object[]
{
(object)EF.Property<int>(EntityShaperExpression:
EntityType: Child
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "EntityId"),
(object)EF.Property<int>(EntityShaperExpression:
EntityType: Child
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id")
} != null && new object[]
{
(object)EF.Property<int>(EntityShaperExpression:
EntityType: Child
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "EntityId"),
(object)EF.Property<int>(EntityShaperExpression:
EntityType: Child
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
, "Id")
} == new object[]
{
(object)EF.Property<int>(namelessParameter{0}, "ChildEntityId"),
(object)EF.Property<int>(namelessParameter{0}, "ChildId")
})' 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'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.IncludeExpression.VisitChildren(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
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 System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.TranslateSubquery(Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.IncludeExpression.VisitChildren(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
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 System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorTResult
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQueryTResult
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCoreTResult
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_01.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsyncTResult
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsyncTResult
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetAsyncEnumerator(CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.System.Collections.Generic.IAsyncEnumerable
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken)
at EFProjectionRepro.Program.Main(String[] args) in route/to/file.cs:line 17
at EFProjectionRepro.Program.
```
Switching the model to HasMany for both Child and Owned does not cause exception.
EF Core version: 5.0.0-rc.2.20475.6
Database provider:Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 5.0
Operating system: Ubuntu 18.04
IDE: Visual Studio Code 1.50.1
Combination of https://github.com/dotnet/efcore/pull/20556 https://github.com/dotnet/efcore/pull/20644
Issue: When OwnsMany parent has a composite PK, translation will fail.
Root Cause: we are still matching for NewExpression for key values check which we converted to NewArrayExpression at some point.
https://github.com/dotnet/efcore/blob/25727cd85621535451b16e5590ec42d35c6e80b9/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs#L1350-L1352
Above needs to do processing like https://github.com/dotnet/efcore/blob/25727cd85621535451b16e5590ec42d35c6e80b9/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.ExpressionVisitors.cs#L395-L407
@smitpatel Regression?
@ajcvickers - Possible. Many changes affected this area in 5.0. I did not test on 3.1
@ajcvickers - Confirmed this regression from 3.1 release.
@smitpatel Let's prepare a fix for Tactics.
@ajcvickers - Done in https://github.com/dotnet/efcore/pull/23143
Most helpful comment
@ajcvickers - Done in https://github.com/dotnet/efcore/pull/23143