From 39c48e0db0c2150c46d0f91f99257dd90618de1d Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Wed, 13 Jan 2021 09:17:12 -0800 Subject: [PATCH] [5.0.3] InMemory: Wrap composite key selector for owned type in AnonymousObject (#23732) * InMemory: Wrap composite key selector for owned type in AnonymousObject Resolves #23687 Composite key selector needs wrapper so that we compare them component-wise * Update InMemoryQueryableMethodTranslatingExpressionVisitor.cs --- ...yableMethodTranslatingExpressionVisitor.cs | 7 +++ .../Query/QueryBugsInMemoryTest.cs | 57 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs index 3718215ba7d..b62f0acce1a 100644 --- a/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/EFCore.InMemory/Query/Internal/InMemoryQueryableMethodTranslatingExpressionVisitor.cs @@ -1479,6 +1479,13 @@ ProjectionBindingExpression projectionBindingExpression : foreignKey.Properties, makeNullable); + if (foreignKey.Properties.Count > 1 + && !(AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore23687", out var enabled) && enabled)) + { + outerKey = Expression.New(AnonymousObject.AnonymousObjectCtor, outerKey); + innerKey = Expression.New(AnonymousObject.AnonymousObjectCtor, innerKey); + } + var outerKeySelector = Expression.Lambda(_expressionTranslator.Translate(outerKey), _queryExpression.CurrentParameter); var innerKeySelector = Expression.Lambda( _expressionTranslator.Translate(innerKey), innerQueryExpression.CurrentParameter); diff --git a/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs index 157c8cee064..b9237457dea 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/QueryBugsInMemoryTest.cs @@ -1103,6 +1103,63 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) #endregion + #region Issue23687 + + [ConditionalFact] + public virtual void Owned_reference_with_composite_key() + { + using (CreateScratch(Seed23687, "23687")) + { + using var context = new MyContext23687(); + + var query = context.Table.ToList(); + + var root = Assert.Single(query); + Assert.Equal("A", root.OwnedProp.A); + Assert.Equal("B", root.OwnedProp.B); + } + } + + private static void Seed23687(MyContext23687 context) + { + context.Table.Add(new Root23687 { Id1 = 1, Id2 = 11, OwnedProp = new OwnedClass23687 { A = "A", B = "B" } }); + + context.SaveChanges(); + } + + [Owned] + public class OwnedClass23687 + { + public string A { get; set; } + public string B { get; set; } + } + + public class Root23687 + { + public int Id1 { get; set; } + public int Id2 { get; set; } + public OwnedClass23687 OwnedProp { get; set; } + } + + private class MyContext23687 : DbContext + { + public DbSet Table { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder + .UseInternalServiceProvider(InMemoryFixture.DefaultServiceProvider) + .UseInMemoryDatabase("23687"); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(e => new { e.Id1, e.Id2 }); + } + } + + #endregion + #region SharedHelper private static InMemoryTestStore CreateScratch(Action seed, string databaseName)