Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to #23779 - TryRewriteEntityEquality and NotEqual comparison of CompositePrimaryKey #23821

Merged
merged 3 commits into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,9 @@ private bool TryRewriteEntityEquality(ExpressionType nodeType, Expression left,
nodeType,
CreatePropertyAccessExpression(left, p),
CreatePropertyAccessExpression(right, p)))
.Aggregate((l, r) => Expression.AndAlso(l, r)));
.Aggregate((l, r) => nodeType == ExpressionType.Equal
? Expression.AndAlso(l, r)
: Expression.OrElse(l, r)));

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,9 @@ private bool TryRewriteEntityEquality(
nodeType,
CreatePropertyAccessExpression(left, p),
CreatePropertyAccessExpression(right, p)))
.Aggregate((l, r) => Expression.AndAlso(l, r)));
.Aggregate((l, r) => nodeType == ExpressionType.Equal
? Expression.AndAlso(l, r)
: Expression.OrElse(l, r)));

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1406,7 +1406,9 @@ private bool TryRewriteEntityEquality(
return nodeType == ExpressionType.Equal
? (Expression)comparison
: Expression.Not(comparison);
}).Aggregate((l, r) => Expression.AndAlso(l, r)));
}).Aggregate((l, r) => nodeType == ExpressionType.Equal
maumar marked this conversation as resolved.
Show resolved Hide resolved
? Expression.AndAlso(l, r)
: Expression.OrElse(l, r)));

return true;
}
Expand Down
58 changes: 56 additions & 2 deletions test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7960,9 +7960,9 @@ public virtual Task Array_access_on_byte_array(bool async)

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task Project_shadow_properties(bool async)
public virtual Task Project_shadow_properties(bool async)
{
await AssertQuery(
return AssertQuery(
async,
ss => from g in ss.Set<Gear>()
select new
Expand All @@ -7973,6 +7973,60 @@ await AssertQuery(
elementSorter: e => e.Nickname);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Composite_key_entity_equal(bool async)
{
return AssertQuery(
async,
ss => from g1 in ss.Set<Gear>()
from g2 in ss.Set<Gear>()
where g1 == g2
select new { g1, g2 },
elementSorter: e => (e.g1.Nickname, e.g2.Nickname),
elementAsserter: (e, a) =>
{
AssertEqual(e.g1, a.g1);
AssertEqual(e.g2, a.g2);
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Composite_key_entity_not_equal(bool async)
{
return AssertQuery(
async,
ss => from g1 in ss.Set<Gear>()
from g2 in ss.Set<Gear>()
where g1 != g2
select new { g1, g2 },
elementSorter: e => (e.g1.Nickname, e.g2.Nickname),
elementAsserter: (e, a) =>
{
AssertEqual(e.g1, a.g1);
AssertEqual(e.g2, a.g2);
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Composite_key_entity_equal_null(bool async)
{
return AssertQuery(
async,
ss => ss.Set<LocustLeader>().OfType<LocustCommander>().Where(lc => lc.DefeatedBy == null));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Composite_key_entity_not_equal_null(bool async)
{
return AssertQuery(
async,
ss => ss.Set<LocustLeader>().OfType<LocustCommander>().Where(lc => lc.DefeatedBy != null));
}

protected GearsOfWarContext CreateContext()
=> Fixture.CreateContext();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7399,6 +7399,50 @@ FROM [LocustLeaders] AS [l]
WHERE [l].[Discriminator] = N'LocustCommander'");
}

public override async Task Composite_key_entity_equal(bool async)
{
await base.Composite_key_entity_equal(async);

AssertSql(
@"SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[Rank]
FROM [Gears] AS [g]
CROSS JOIN [Gears] AS [g0]
WHERE ([g].[Nickname] = [g0].[Nickname]) AND ([g].[SquadId] = [g0].[SquadId])");
}

public override async Task Composite_key_entity_not_equal(bool async)
{
await base.Composite_key_entity_not_equal(async);

AssertSql(
@"SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], [g0].[Nickname], [g0].[SquadId], [g0].[AssignedCityName], [g0].[CityOfBirthName], [g0].[Discriminator], [g0].[FullName], [g0].[HasSoulPatch], [g0].[LeaderNickname], [g0].[LeaderSquadId], [g0].[Rank]
FROM [Gears] AS [g]
CROSS JOIN [Gears] AS [g0]
WHERE ([g].[Nickname] <> [g0].[Nickname]) OR ([g].[SquadId] <> [g0].[SquadId])");
}

public override async Task Composite_key_entity_equal_null(bool async)
{
await base.Composite_key_entity_equal_null(async);

AssertSql(
@"SELECT [l].[Name], [l].[Discriminator], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l].[DefeatedByNickname], [l].[DefeatedBySquadId], [l].[HighCommandId]
FROM [LocustLeaders] AS [l]
LEFT JOIN [Gears] AS [g] ON ([l].[DefeatedByNickname] = [g].[Nickname]) AND ([l].[DefeatedBySquadId] = [g].[SquadId])
WHERE ([l].[Discriminator] = N'LocustCommander') AND ([g].[Nickname] IS NULL OR [g].[SquadId] IS NULL)");
}

public override async Task Composite_key_entity_not_equal_null(bool async)
{
await base.Composite_key_entity_not_equal_null(async);

AssertSql(
@"SELECT [l].[Name], [l].[Discriminator], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l].[DefeatedByNickname], [l].[DefeatedBySquadId], [l].[HighCommandId]
FROM [LocustLeaders] AS [l]
LEFT JOIN [Gears] AS [g] ON ([l].[DefeatedByNickname] = [g].[Nickname]) AND ([l].[DefeatedBySquadId] = [g].[SquadId])
WHERE ([l].[Discriminator] = N'LocustCommander') AND ([g].[Nickname] IS NOT NULL AND [g].[SquadId] IS NOT NULL)");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Expand Down