Skip to content

Commit

Permalink
Merge in 'release/7.0' changes
Browse files Browse the repository at this point in the history
  • Loading branch information
dotnet-bot committed Oct 4, 2023
2 parents f16e454 + 748bfee commit e629bc8
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 12 deletions.
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup Label="Version settings">
<VersionPrefix>7.0.12</VersionPrefix>
<VersionPrefix>7.0.13</VersionPrefix>
<PreReleaseVersionLabel>servicing</PreReleaseVersionLabel>
<IncludeSourceRevisionInInformationalVersion>False</IncludeSourceRevisionInInformationalVersion>
<IsServicingBuild Condition="'$(PreReleaseVersionLabel)' == 'servicing'">true</IsServicingBuild>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ namespace Microsoft.EntityFrameworkCore.Query;
/// </summary>
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<MethodInfo> SingleResultMethodInfos = new()
Expand Down Expand Up @@ -1671,19 +1674,33 @@ private bool TryRewriteEntityEquality(
if (allNonPrincipalSharedNonPkProperties.Count != 0
&& allNonPrincipalSharedNonPkProperties.All(p => p.IsNullable))
{
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));
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));
}

condition = condition == null
? atLeastOneNonNullValueInNullablePropertyCondition
? optionalPropertiesCondition
: nodeType == ExpressionType.Equal
? Expression.OrElse(condition, atLeastOneNonNullValueInNullablePropertyCondition)
: Expression.AndAlso(condition, atLeastOneNonNullValueInNullablePropertyCondition);
? Expression.OrElse(condition, optionalPropertiesCondition)
: Expression.AndAlso(condition, optionalPropertiesCondition);
}

if (condition != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,64 @@ 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<MyContext28247>(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<MyContext28247>(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)
Expand Down Expand Up @@ -364,6 +422,12 @@ 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; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,37 @@ 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) AND ([r].[Rot_ServiceType] IS NOT NULL)
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]
""");
}

Expand Down

0 comments on commit e629bc8

Please sign in to comment.