From 9e1289d513d8eadd650edbc311ae6cdb03c07b14 Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Wed, 28 Apr 2021 20:51:30 -0700 Subject: [PATCH] Add regression test for #24777 (#24791) --- .../OwnedEntityQueryRelationalTestBase.cs | 100 ++++++++++++++++++ .../Query/OwnedEntityQuerySqlServerTest.cs | 24 +++++ 2 files changed, 124 insertions(+) diff --git a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs index 4938a2f6e25..13575a4fc20 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs @@ -1,7 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.TestUtilities; +using Xunit; namespace Microsoft.EntityFrameworkCore.Query { @@ -13,5 +17,101 @@ protected TestSqlLoggerFactory TestSqlLoggerFactory protected void ClearLog() => TestSqlLoggerFactory.Clear(); protected void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Multiple_owned_reference_mapped_to_own_table_containing_owned_collection_in_split_query(bool async) + { + var contextFactory = await InitializeAsync(); + + using (var context = contextFactory.CreateContext()) + { + var root3 = await context.Roots.Where(e => e.Id == 3).AsSplitQuery().SingleAsync(); + + Assert.Equal(2, root3.ModdleA.Leaves.Count); + } + } + + protected class Context24777 : DbContext + { + public Context24777(DbContextOptions options) + : base(options) + { + } + + public DbSet Roots { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(b => + { + b.ToTable(nameof(Root24777)); + b.HasKey(x => x.Id); + b.OwnsOne(x => x.ModdleA, ob => + { + ob.ToTable(nameof(ModdleA24777)); + ob.HasKey(x => x.Id); + ob.WithOwner().HasForeignKey(e => e.RootId); + ob.OwnsMany(x => x.Leaves, oob => + { + oob.ToTable(nameof(Leaf24777)); + oob.HasKey(x => new { ProductCommissionRulesetId = x.ModdleAId, x.UnitThreshold }); + oob.WithOwner().HasForeignKey(e => e.ModdleAId); + oob.HasData( + new Leaf24777 { ModdleAId = 1, UnitThreshold = 1 }, + new Leaf24777 { ModdleAId = 3, UnitThreshold = 1 }, + new Leaf24777 { ModdleAId = 3, UnitThreshold = 15 }); + }); + + ob.HasData( + new ModdleA24777 { Id = 1, RootId = 1 }, + new ModdleA24777 { Id = 2, RootId = 2 }, + new ModdleA24777 { Id = 3, RootId = 3 }); + }); + + b.OwnsOne(x => x.MiddleB, ob => + { + ob.ToTable(nameof(MiddleB24777)); + ob.HasKey(x => x.Id); + ob.WithOwner().HasForeignKey(e => e.RootId); + ob.HasData( + new MiddleB24777 { Id = 1, RootId = 1, Enabled = true }, + new MiddleB24777 { Id = 2, RootId = 3, Enabled = true }); + }); + + b.HasData( + new Root24777 { Id = 1 }, + new Root24777 { Id = 2 }, + new Root24777 { Id = 3 }); + }); + } + } + + protected class Root24777 + { + public int Id { get; init; } + public ModdleA24777 ModdleA { get; init; } + public MiddleB24777 MiddleB { get; init; } + } + + protected class ModdleA24777 + { + public int Id { get; init; } + public int RootId { get; init; } + public List Leaves { get; init; } + } + + protected class MiddleB24777 + { + public int Id { get; init; } + public int RootId { get; init; } + public bool Enabled { get; init; } + } + + protected class Leaf24777 + { + public int ModdleAId { get; init; } + public int UnitThreshold { get; init; } + } } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs index b335aa2f782..320c311e444 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs @@ -37,5 +37,29 @@ FROM [Child20277] AS [c0] WHERE [t2].[row] <= 1 ) AS [t1] ON [e].[Id] = [t1].[Entity20277Id]"); } + + public override async Task Multiple_owned_reference_mapped_to_own_table_containing_owned_collection_in_split_query(bool async) + { + await base.Multiple_owned_reference_mapped_to_own_table_containing_owned_collection_in_split_query(async); + + AssertSql( + @"SELECT TOP(2) [r].[Id], [m].[Id], [m].[Enabled], [m].[RootId], [m0].[Id], [m0].[RootId] +FROM [Root24777] AS [r] +LEFT JOIN [MiddleB24777] AS [m] ON [r].[Id] = [m].[RootId] +LEFT JOIN [ModdleA24777] AS [m0] ON [r].[Id] = [m0].[RootId] +WHERE [r].[Id] = 3 +ORDER BY [r].[Id], [m].[Id], [m0].[Id]", + // + @"SELECT [l].[ModdleAId], [l].[UnitThreshold], [t].[Id], [t].[Id0], [t].[Id1] +FROM ( + SELECT TOP(1) [r].[Id], [m].[Id] AS [Id0], [m0].[Id] AS [Id1] + FROM [Root24777] AS [r] + LEFT JOIN [MiddleB24777] AS [m] ON [r].[Id] = [m].[RootId] + LEFT JOIN [ModdleA24777] AS [m0] ON [r].[Id] = [m0].[RootId] + WHERE [r].[Id] = 3 +) AS [t] +INNER JOIN [Leaf24777] AS [l] ON [t].[Id1] = [l].[ModdleAId] +ORDER BY [t].[Id], [t].[Id0], [t].[Id1]"); + } } }