From 38c348e9ad16213ac0dca02bce6e3735407b4c00 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Tue, 16 Apr 2024 18:00:15 +0300 Subject: [PATCH 1/2] Fix parameter names for nested types in complex type equality (#33527) Fixes #33449 (cherry picked from commit 89e9446ccd7412eb00103434dbe8a905cbc97705) --- ...lationalSqlTranslatingExpressionVisitor.cs | 30 ++++++++-- .../InMemoryComplianceTest.cs | 1 + .../Query/AdHocComplexTypeQueryTestBase.cs | 56 +++++++++++++++++++ .../AdHocComplexTypeQuerySqlServerTest.cs | 32 +++++++++++ .../Query/ComplexTypeQuerySqlServerTest.cs | 24 ++++---- .../Query/AdHocComplexTypeQuerySqliteTest.cs | 10 ++++ .../Query/ComplexTypeQuerySqliteTest.cs | 24 ++++---- 7 files changed, 149 insertions(+), 28 deletions(-) create mode 100644 test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs create mode 100644 test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs create mode 100644 test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs index a9932d09def..4a42e26c611 100644 --- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics.CodeAnalysis; +using System.Text; using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query.SqlExpressions; @@ -60,6 +61,9 @@ public class RelationalSqlTranslatingExpressionVisitor : ExpressionVisitor private bool _throwForNotTranslatedEfProperty; + private static readonly bool UseOldBehavior33449 = + AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue33449", out var enabled33449) && enabled33449; + /// /// Creates a new instance of the class. /// @@ -2045,11 +2049,29 @@ private Expression CreatePropertyAccessExpression(Expression target, IProperty p Expression.Constant(property, typeof(IProperty))), QueryCompilationContext.QueryContextParameter); - var newParameterName = - $"{RuntimeParameterPrefix}" - + $"{chainExpression.ParameterExpression.Name[QueryCompilationContext.QueryParameterPrefix.Length..]}_{property.Name}"; + if (UseOldBehavior33449) + { + var newParameterName = + $"{RuntimeParameterPrefix}" + + $"{chainExpression.ParameterExpression.Name[QueryCompilationContext.QueryParameterPrefix.Length..]}_{property.Name}"; - return _queryCompilationContext.RegisterRuntimeParameter(newParameterName, lambda); + return _queryCompilationContext.RegisterRuntimeParameter(newParameterName, lambda); + } + else + { + var parameterNameBuilder = new StringBuilder(RuntimeParameterPrefix) + .Append(chainExpression.ParameterExpression.Name[QueryCompilationContext.QueryParameterPrefix.Length..]) + .Append('_'); + + foreach (var complexProperty in chainExpression.ComplexPropertyChain) + { + parameterNameBuilder.Append(complexProperty.Name).Append('_'); + } + + parameterNameBuilder.Append(property.Name); + + return _queryCompilationContext.RegisterRuntimeParameter(parameterNameBuilder.ToString(), lambda); + } } case MemberInitExpression memberInitExpression diff --git a/test/EFCore.InMemory.FunctionalTests/InMemoryComplianceTest.cs b/test/EFCore.InMemory.FunctionalTests/InMemoryComplianceTest.cs index c6539c804e2..666a22e8a8e 100644 --- a/test/EFCore.InMemory.FunctionalTests/InMemoryComplianceTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/InMemoryComplianceTest.cs @@ -9,6 +9,7 @@ public class InMemoryComplianceTest : ComplianceTestBase { // No in-memory tests typeof(ComplexTypeQueryTestBase<>), + typeof(AdHocComplexTypeQueryTestBase), typeof(PrimitiveCollectionsQueryTestBase<>), typeof(NonSharedPrimitiveCollectionsQueryTestBase), typeof(FunkyDataQueryTestBase<>), diff --git a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs new file mode 100644 index 00000000000..84f9c74ddd8 --- /dev/null +++ b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +// ReSharper disable ClassNeverInstantiated.Local + +public abstract class AdHocComplexTypeQueryTestBase : NonSharedModelTestBase +{ + #region 33449 + + [ConditionalFact] + public virtual Task Complex_type_equals_parameter_with_nested_types_with_property_of_same_name() + { + throw new NotImplementedException(); + } + + private class Context33449(DbContextOptions options) : DbContext(options) + { + protected override void OnModelCreating(ModelBuilder modelBuilder) + => modelBuilder.Entity().ComplexProperty(b => b.ComplexContainer, x => + { + x.ComplexProperty(c => c.Containee1); + x.ComplexProperty(c => c.Containee2); + }); + + public class EntityType + { + public int Id { get; set; } + public ComplexContainer ComplexContainer { get; set; } = null!; + } + + public class ComplexContainer + { + public int Id { get; set; } + + public ComplexContainee1 Containee1 { get; set; } = null!; + public ComplexContainee2 Containee2 { get; set; } = null!; + } + + public class ComplexContainee1 + { + public int Id { get; set; } + } + + public class ComplexContainee2 + { + public int Id { get; set; } + } + } + + #endregion 33449 + + protected override string StoreName + => "AdHocComplexTypeQueryTest"; +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs new file mode 100644 index 00000000000..4438bd8366f --- /dev/null +++ b/test/EFCore.SqlServer.FunctionalTests/Query/AdHocComplexTypeQuerySqlServerTest.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +public class AdHocComplexTypeQuerySqlServerTest : AdHocComplexTypeQueryTestBase +{ + public override async Task Complex_type_equals_parameter_with_nested_types_with_property_of_same_name() + { + await base.Complex_type_equals_parameter_with_nested_types_with_property_of_same_name(); + + AssertSql( + """ +@__entity_equality_container_0_Id='1' (Nullable = true) +@__entity_equality_container_0_Containee1_Id='2' (Nullable = true) +@__entity_equality_container_0_Containee2_Id='3' (Nullable = true) + +SELECT TOP(2) [e].[Id], [e].[ComplexContainer_Id], [e].[ComplexContainer_Containee1_Id], [e].[ComplexContainer_Containee2_Id] +FROM [EntityType] AS [e] +WHERE [e].[ComplexContainer_Id] = @__entity_equality_container_0_Id AND [e].[ComplexContainer_Containee1_Id] = @__entity_equality_container_0_Containee1_Id AND [e].[ComplexContainer_Containee2_Id] = @__entity_equality_container_0_Containee2_Id +"""); + } + + protected TestSqlLoggerFactory TestSqlLoggerFactory + => (TestSqlLoggerFactory)ListLoggerFactory; + + protected void AssertSql(params string[] expected) + => TestSqlLoggerFactory.AssertBaseline(expected); + + protected override ITestStoreFactory TestStoreFactory + => SqlServerTestStoreFactory.Instance; +} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs index 9c72bf3aebe..ca364de7b02 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexTypeQuerySqlServerTest.cs @@ -233,12 +233,12 @@ public override async Task Complex_type_equals_parameter(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 4000) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 4000) -@__entity_equality_address_0_FullName='United States' (Size = 4000) +@__entity_equality_address_0_Country_Code='US' (Size = 4000) +@__entity_equality_address_0_Country_FullName='United States' (Size = 4000) SELECT [c].[Id], [c].[Name], [c].[BillingAddress_AddressLine1], [c].[BillingAddress_AddressLine2], [c].[BillingAddress_ZipCode], [c].[BillingAddress_Country_Code], [c].[BillingAddress_Country_FullName], [c].[ShippingAddress_AddressLine1], [c].[ShippingAddress_AddressLine2], [c].[ShippingAddress_ZipCode], [c].[ShippingAddress_Country_Code], [c].[ShippingAddress_Country_FullName] FROM [Customer] AS [c] -WHERE [c].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [c].[ShippingAddress_AddressLine2] IS NULL AND [c].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [c].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Code AND [c].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_FullName +WHERE [c].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [c].[ShippingAddress_AddressLine2] IS NULL AND [c].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [c].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Country_Code AND [c].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_Country_FullName """); } @@ -264,15 +264,15 @@ public override async Task Contains_over_complex_type(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 4000) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 4000) -@__entity_equality_address_0_FullName='United States' (Size = 4000) +@__entity_equality_address_0_Country_Code='US' (Size = 4000) +@__entity_equality_address_0_Country_FullName='United States' (Size = 4000) SELECT [c].[Id], [c].[Name], [c].[BillingAddress_AddressLine1], [c].[BillingAddress_AddressLine2], [c].[BillingAddress_ZipCode], [c].[BillingAddress_Country_Code], [c].[BillingAddress_Country_FullName], [c].[ShippingAddress_AddressLine1], [c].[ShippingAddress_AddressLine2], [c].[ShippingAddress_ZipCode], [c].[ShippingAddress_Country_Code], [c].[ShippingAddress_Country_FullName] FROM [Customer] AS [c] WHERE EXISTS ( SELECT 1 FROM [Customer] AS [c0] - WHERE [c0].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [c0].[ShippingAddress_AddressLine2] IS NULL AND [c0].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [c0].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Code AND [c0].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_FullName) + WHERE [c0].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [c0].[ShippingAddress_AddressLine2] IS NULL AND [c0].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [c0].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Country_Code AND [c0].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_Country_FullName) """); } @@ -600,12 +600,12 @@ public override async Task Struct_complex_type_equals_parameter(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 4000) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 4000) -@__entity_equality_address_0_FullName='United States' (Size = 4000) +@__entity_equality_address_0_Country_Code='US' (Size = 4000) +@__entity_equality_address_0_Country_FullName='United States' (Size = 4000) SELECT [v].[Id], [v].[Name], [v].[BillingAddress_AddressLine1], [v].[BillingAddress_AddressLine2], [v].[BillingAddress_ZipCode], [v].[BillingAddress_Country_Code], [v].[BillingAddress_Country_FullName], [v].[ShippingAddress_AddressLine1], [v].[ShippingAddress_AddressLine2], [v].[ShippingAddress_ZipCode], [v].[ShippingAddress_Country_Code], [v].[ShippingAddress_Country_FullName] FROM [ValuedCustomer] AS [v] -WHERE [v].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [v].[ShippingAddress_AddressLine2] IS NULL AND [v].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [v].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Code AND [v].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_FullName +WHERE [v].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [v].[ShippingAddress_AddressLine2] IS NULL AND [v].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [v].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Country_Code AND [v].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_Country_FullName """); } @@ -624,15 +624,15 @@ public override async Task Contains_over_struct_complex_type(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 4000) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 4000) -@__entity_equality_address_0_FullName='United States' (Size = 4000) +@__entity_equality_address_0_Country_Code='US' (Size = 4000) +@__entity_equality_address_0_Country_FullName='United States' (Size = 4000) SELECT [v].[Id], [v].[Name], [v].[BillingAddress_AddressLine1], [v].[BillingAddress_AddressLine2], [v].[BillingAddress_ZipCode], [v].[BillingAddress_Country_Code], [v].[BillingAddress_Country_FullName], [v].[ShippingAddress_AddressLine1], [v].[ShippingAddress_AddressLine2], [v].[ShippingAddress_ZipCode], [v].[ShippingAddress_Country_Code], [v].[ShippingAddress_Country_FullName] FROM [ValuedCustomer] AS [v] WHERE EXISTS ( SELECT 1 FROM [ValuedCustomer] AS [v0] - WHERE [v0].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [v0].[ShippingAddress_AddressLine2] IS NULL AND [v0].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [v0].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Code AND [v0].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_FullName) + WHERE [v0].[ShippingAddress_AddressLine1] = @__entity_equality_address_0_AddressLine1 AND [v0].[ShippingAddress_AddressLine2] IS NULL AND [v0].[ShippingAddress_ZipCode] = @__entity_equality_address_0_ZipCode AND [v0].[ShippingAddress_Country_Code] = @__entity_equality_address_0_Country_Code AND [v0].[ShippingAddress_Country_FullName] = @__entity_equality_address_0_Country_FullName) """); } diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs new file mode 100644 index 00000000000..f9aa99e7c4a --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Query/AdHocComplexTypeQuerySqliteTest.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Query; + +public class AdHocComplexTypeQuerySqliteTest : AdHocComplexTypeQueryTestBase +{ + protected override ITestStoreFactory TestStoreFactory + => SqliteTestStoreFactory.Instance; +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs index 51c426cd289..69f1fbcf411 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/ComplexTypeQuerySqliteTest.cs @@ -231,12 +231,12 @@ public override async Task Complex_type_equals_parameter(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 21) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 2) -@__entity_equality_address_0_FullName='United States' (Size = 13) +@__entity_equality_address_0_Country_Code='US' (Size = 2) +@__entity_equality_address_0_Country_FullName='United States' (Size = 13) SELECT "c"."Id", "c"."Name", "c"."BillingAddress_AddressLine1", "c"."BillingAddress_AddressLine2", "c"."BillingAddress_ZipCode", "c"."BillingAddress_Country_Code", "c"."BillingAddress_Country_FullName", "c"."ShippingAddress_AddressLine1", "c"."ShippingAddress_AddressLine2", "c"."ShippingAddress_ZipCode", "c"."ShippingAddress_Country_Code", "c"."ShippingAddress_Country_FullName" FROM "Customer" AS "c" -WHERE "c"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "c"."ShippingAddress_AddressLine2" IS NULL AND "c"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "c"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Code AND "c"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_FullName +WHERE "c"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "c"."ShippingAddress_AddressLine2" IS NULL AND "c"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "c"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Country_Code AND "c"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_Country_FullName """); } @@ -262,15 +262,15 @@ public override async Task Contains_over_complex_type(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 21) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 2) -@__entity_equality_address_0_FullName='United States' (Size = 13) +@__entity_equality_address_0_Country_Code='US' (Size = 2) +@__entity_equality_address_0_Country_FullName='United States' (Size = 13) SELECT "c"."Id", "c"."Name", "c"."BillingAddress_AddressLine1", "c"."BillingAddress_AddressLine2", "c"."BillingAddress_ZipCode", "c"."BillingAddress_Country_Code", "c"."BillingAddress_Country_FullName", "c"."ShippingAddress_AddressLine1", "c"."ShippingAddress_AddressLine2", "c"."ShippingAddress_ZipCode", "c"."ShippingAddress_Country_Code", "c"."ShippingAddress_Country_FullName" FROM "Customer" AS "c" WHERE EXISTS ( SELECT 1 FROM "Customer" AS "c0" - WHERE "c0"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "c0"."ShippingAddress_AddressLine2" IS NULL AND "c0"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "c0"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Code AND "c0"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_FullName) + WHERE "c0"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "c0"."ShippingAddress_AddressLine2" IS NULL AND "c0"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "c0"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Country_Code AND "c0"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_Country_FullName) """); } @@ -598,12 +598,12 @@ public override async Task Struct_complex_type_equals_parameter(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 21) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 2) -@__entity_equality_address_0_FullName='United States' (Size = 13) +@__entity_equality_address_0_Country_Code='US' (Size = 2) +@__entity_equality_address_0_Country_FullName='United States' (Size = 13) SELECT "v"."Id", "v"."Name", "v"."BillingAddress_AddressLine1", "v"."BillingAddress_AddressLine2", "v"."BillingAddress_ZipCode", "v"."BillingAddress_Country_Code", "v"."BillingAddress_Country_FullName", "v"."ShippingAddress_AddressLine1", "v"."ShippingAddress_AddressLine2", "v"."ShippingAddress_ZipCode", "v"."ShippingAddress_Country_Code", "v"."ShippingAddress_Country_FullName" FROM "ValuedCustomer" AS "v" -WHERE "v"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "v"."ShippingAddress_AddressLine2" IS NULL AND "v"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "v"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Code AND "v"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_FullName +WHERE "v"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "v"."ShippingAddress_AddressLine2" IS NULL AND "v"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "v"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Country_Code AND "v"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_Country_FullName """); } @@ -622,15 +622,15 @@ public override async Task Contains_over_struct_complex_type(bool async) """ @__entity_equality_address_0_AddressLine1='804 S. Lakeshore Road' (Size = 21) @__entity_equality_address_0_ZipCode='38654' (Nullable = true) -@__entity_equality_address_0_Code='US' (Size = 2) -@__entity_equality_address_0_FullName='United States' (Size = 13) +@__entity_equality_address_0_Country_Code='US' (Size = 2) +@__entity_equality_address_0_Country_FullName='United States' (Size = 13) SELECT "v"."Id", "v"."Name", "v"."BillingAddress_AddressLine1", "v"."BillingAddress_AddressLine2", "v"."BillingAddress_ZipCode", "v"."BillingAddress_Country_Code", "v"."BillingAddress_Country_FullName", "v"."ShippingAddress_AddressLine1", "v"."ShippingAddress_AddressLine2", "v"."ShippingAddress_ZipCode", "v"."ShippingAddress_Country_Code", "v"."ShippingAddress_Country_FullName" FROM "ValuedCustomer" AS "v" WHERE EXISTS ( SELECT 1 FROM "ValuedCustomer" AS "v0" - WHERE "v0"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "v0"."ShippingAddress_AddressLine2" IS NULL AND "v0"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "v0"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Code AND "v0"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_FullName) + WHERE "v0"."ShippingAddress_AddressLine1" = @__entity_equality_address_0_AddressLine1 AND "v0"."ShippingAddress_AddressLine2" IS NULL AND "v0"."ShippingAddress_ZipCode" = @__entity_equality_address_0_ZipCode AND "v0"."ShippingAddress_Country_Code" = @__entity_equality_address_0_Country_Code AND "v0"."ShippingAddress_Country_FullName" = @__entity_equality_address_0_Country_FullName) """); } From c86702d3f62ae1cd35df9be5fdbe513c50447add Mon Sep 17 00:00:00 2001 From: maumar Date: Tue, 16 Apr 2024 18:25:02 -0700 Subject: [PATCH 2/2] adding missing test code --- .../Query/AdHocComplexTypeQueryTestBase.cs | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs index 84f9c74ddd8..93e1a435cd3 100644 --- a/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/AdHocComplexTypeQueryTestBase.cs @@ -10,9 +10,34 @@ public abstract class AdHocComplexTypeQueryTestBase : NonSharedModelTestBase #region 33449 [ConditionalFact] - public virtual Task Complex_type_equals_parameter_with_nested_types_with_property_of_same_name() + public virtual async Task Complex_type_equals_parameter_with_nested_types_with_property_of_same_name() { - throw new NotImplementedException(); + var contextFactory = await InitializeAsync( + seed: context => + { + context.AddRange( + new Context33449.EntityType + { + ComplexContainer = new() + { + Id = 1, + Containee1 = new() { Id = 2 }, + Containee2 = new() { Id = 3 } + } + }); + context.SaveChanges(); + }); + + await using var context = contextFactory.CreateContext(); + + var container = new Context33449.ComplexContainer + { + Id = 1, + Containee1 = new() { Id = 2 }, + Containee2 = new() { Id = 3 } + }; + + _ = await context.Set().Where(b => b.ComplexContainer == container).SingleAsync(); } private class Context33449(DbContextOptions options) : DbContext(options) @@ -20,8 +45,9 @@ private class Context33449(DbContextOptions options) : DbContext(options) protected override void OnModelCreating(ModelBuilder modelBuilder) => modelBuilder.Entity().ComplexProperty(b => b.ComplexContainer, x => { - x.ComplexProperty(c => c.Containee1); - x.ComplexProperty(c => c.Containee2); + x.IsRequired(); + x.ComplexProperty(c => c.Containee1).IsRequired(); + x.ComplexProperty(c => c.Containee2).IsRequired(); }); public class EntityType