diff --git a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs index 7b94b87815a..6bd690a1ad2 100644 --- a/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs +++ b/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs @@ -20,9 +20,6 @@ namespace Microsoft.EntityFrameworkCore.Query; /// public class RelationalSqlTranslatingExpressionVisitor : ExpressionVisitor { - private static readonly bool UseOldBehavior30996 - = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue30996", out var enabled30996) && enabled30996; - private const string RuntimeParameterPrefix = QueryCompilationContext.QueryParameterPrefix + "entity_equality_"; private static readonly List SingleResultMethodInfos = new() @@ -1674,33 +1671,19 @@ private bool TryRewriteEntityEquality( if (allNonPrincipalSharedNonPkProperties.Count != 0 && allNonPrincipalSharedNonPkProperties.All(p => p.IsNullable)) { - Expression? optionalPropertiesCondition; - if (!UseOldBehavior30996) - { - optionalPropertiesCondition = allNonPrincipalSharedNonPkProperties - .Select( - p => Infrastructure.ExpressionExtensions.CreateEqualsExpression( - CreatePropertyAccessExpression(nonNullEntityReference, p), - Expression.Constant(null, p.ClrType.MakeNullable()), - nodeType != ExpressionType.Equal)) - .Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.AndAlso(l, r) : Expression.OrElse(l, r)); - } - else - { - optionalPropertiesCondition = allNonPrincipalSharedNonPkProperties - .Select( - p => Infrastructure.ExpressionExtensions.CreateEqualsExpression( - CreatePropertyAccessExpression(nonNullEntityReference, p), - Expression.Constant(null, p.ClrType.MakeNullable()), - nodeType != ExpressionType.Equal)) - .Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.OrElse(l, r) : Expression.AndAlso(l, r)); - } + var atLeastOneNonNullValueInNullablePropertyCondition = allNonPrincipalSharedNonPkProperties + .Select( + p => Infrastructure.ExpressionExtensions.CreateEqualsExpression( + CreatePropertyAccessExpression(nonNullEntityReference, p), + Expression.Constant(null, p.ClrType.MakeNullable()), + nodeType != ExpressionType.Equal)) + .Aggregate((l, r) => nodeType == ExpressionType.Equal ? Expression.OrElse(l, r) : Expression.AndAlso(l, r)); condition = condition == null - ? optionalPropertiesCondition + ? atLeastOneNonNullValueInNullablePropertyCondition : nodeType == ExpressionType.Equal - ? Expression.OrElse(condition, optionalPropertiesCondition) - : Expression.AndAlso(condition, optionalPropertiesCondition); + ? Expression.OrElse(condition, atLeastOneNonNullValueInNullablePropertyCondition) + : Expression.AndAlso(condition, atLeastOneNonNullValueInNullablePropertyCondition); } if (condition != null) diff --git a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs index f559e7266ea..54e78c7f789 100644 --- a/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Query/OwnedEntityQueryRelationalTestBase.cs @@ -284,64 +284,6 @@ public virtual async Task Owned_entity_with_all_null_properties_entity_equality_ }); } - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Owned_entity_with_all_null_properties_in_compared_to_null_in_conditional_projection(bool async) - { - var contextFactory = await InitializeAsync(seed: c => c.Seed()); - - using var context = contextFactory.CreateContext(); - var query = context.RotRutCases - .AsNoTracking() - .OrderBy(e => e.Id) - .Select(e => e.Rot == null ? null : new RotDto { MyApartmentNo = e.Rot.ApartmentNo, MyServiceType = e.Rot.ServiceType }); - - var result = async - ? await query.ToListAsync() - : query.ToList(); - - Assert.Collection( - result, - t => - { - Assert.Equal("1", t.MyApartmentNo); - Assert.Equal(1, t.MyServiceType); - }, - t => - { - Assert.Null(t); - }); - } - - [ConditionalTheory] - [MemberData(nameof(IsAsyncData))] - public virtual async Task Owned_entity_with_all_null_properties_in_compared_to_non_null_in_conditional_projection(bool async) - { - var contextFactory = await InitializeAsync(seed: c => c.Seed()); - - using var context = contextFactory.CreateContext(); - var query = context.RotRutCases - .AsNoTracking() - .OrderBy(e => e.Id) - .Select(e => e.Rot != null ? new RotDto { MyApartmentNo = e.Rot.ApartmentNo, MyServiceType = e.Rot.ServiceType } : null); - - var result = async - ? await query.ToListAsync() - : query.ToList(); - - Assert.Collection( - result, - t => - { - Assert.Equal("1", t.MyApartmentNo); - Assert.Equal(1, t.MyServiceType); - }, - t => - { - Assert.Null(t); - }); - } - [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual async Task Owned_entity_with_all_null_properties_property_access_when_not_containing_another_owned_entity(bool async) @@ -422,12 +364,6 @@ public class Rot public string ApartmentNo { get; set; } } - public class RotDto - { - public int? MyServiceType { get; set; } - public string MyApartmentNo { get; set; } - } - public class Rut { public int? Value { get; set; } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs index 5d739e31b39..cd9b9197536 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/OwnedEntityQuerySqlServerTest.cs @@ -166,37 +166,7 @@ public override async Task Owned_entity_with_all_null_properties_entity_equality """ SELECT [r].[Id], [r].[Rot_ApartmentNo], [r].[Rot_ServiceType] FROM [RotRutCases] AS [r] -WHERE ([r].[Rot_ApartmentNo] IS NOT NULL) OR ([r].[Rot_ServiceType] IS NOT NULL) -"""); - } - - public override async Task Owned_entity_with_all_null_properties_in_compared_to_null_in_conditional_projection(bool async) - { - await base.Owned_entity_with_all_null_properties_in_compared_to_null_in_conditional_projection(async); - - AssertSql( -""" -SELECT CASE - WHEN ([r].[Rot_ApartmentNo] IS NULL) AND ([r].[Rot_ServiceType] IS NULL) THEN CAST(1 AS bit) - ELSE CAST(0 AS bit) -END, [r].[Rot_ApartmentNo], [r].[Rot_ServiceType] -FROM [RotRutCases] AS [r] -ORDER BY [r].[Id] -"""); - } - - public override async Task Owned_entity_with_all_null_properties_in_compared_to_non_null_in_conditional_projection(bool async) - { - await base.Owned_entity_with_all_null_properties_in_compared_to_non_null_in_conditional_projection(async); - - AssertSql( -""" -SELECT CASE - WHEN ([r].[Rot_ApartmentNo] IS NOT NULL) OR ([r].[Rot_ServiceType] IS NOT NULL) THEN CAST(1 AS bit) - ELSE CAST(0 AS bit) -END, [r].[Rot_ApartmentNo], [r].[Rot_ServiceType] -FROM [RotRutCases] AS [r] -ORDER BY [r].[Id] +WHERE ([r].[Rot_ApartmentNo] IS NOT NULL) AND ([r].[Rot_ServiceType] IS NOT NULL) """); }