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 issues around entity comparisons in query #11287

Closed
wants to merge 1 commit into from
Closed
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
144 changes: 144 additions & 0 deletions src/EFCore.Specification.Tests/Query/AsyncGearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1372,5 +1372,149 @@ await AssertQuery<CogTag>(
}),
elementSorter: e => e.c);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys()
{
await AssertQuery<Weapon>(
ws => from w1 in ws
join w2 in ws on w1 equals w2
select new { Name1 = w1.Name, Name2 = w2.Name },
elementSorter: e => e.Name1 + " " + e.Name2);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys_composite_key()
{
await AssertQuery<Gear>(
gs => from g1 in gs
join g2 in gs on g1 equals g2
select new { GearName1 = g1.FullName, GearName2 = g2.FullName },
elementSorter: e => e.GearName1 + " " + e.GearName2);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys_inheritance()
{
await AssertQuery<Gear>(
gs => from g in gs
join o in gs.OfType<Officer>() on g equals o
select new { GearName = g.FullName, OfficerName = o.FullName },
elementSorter: e => e.GearName + " " + e.OfficerName);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys_outer_key_is_navigation()
{
await AssertQuery<Weapon>(
ws => from w1 in ws
join w2 in ws on w1.SynergyWith equals w2
select new { Name1 = w1.Name, Name2 = w2.Name },
elementSorter: e => e.Name1 + " " + e.Name2);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys_inner_key_is_navigation()
{
await AssertQuery<City, Gear>(
(cs, gs) =>
from c in cs
join g in gs on c equals g.AssignedCity
select new { CityName = c.Name, GearNickname = g.Nickname },
e => e.CityName + " " + e.GearNickname);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys_inner_key_is_navigation_composite_key()
{
await AssertQuery<Gear, CogTag>(
(gs, ts) =>
from g in gs
join t in ts.Where(tt => tt.Note == "Cole's Tag" || tt.Note == "Dom's Tag") on g equals t.Gear
select new { g.Nickname, t.Note },
elementSorter: e => e.Nickname + " " + e.Note);
}

[ConditionalFact]
public virtual async Task Join_on_entity_qsre_keys_inner_key_is_nested_navigation()
{
await AssertQuery<Squad, Weapon>(
(ss, ws) =>
from s in ss
join w in ws.Where(ww => ww.IsAutomatic) on s equals w.Owner.Squad
select new { SquadName = s.Name, WeaponName = w.Name },
elementSorter: e => e.SquadName + " " + e.WeaponName);
}

[ConditionalFact]
public virtual async Task GroupJoin_on_entity_qsre_keys_inner_key_is_nested_navigation()
{
await AssertQuery<Squad, Weapon>(
(ss, ws) =>
from s in ss
join w in ws on s equals w.Owner.Squad into grouping
from w in grouping.DefaultIfEmpty()
select new { SquadName = s.Name, WeaponName = w.Name },
(ss, ws) =>
from s in ss
join w in ws on s equals Maybe(w.Owner, () => w.Owner.Squad) into grouping
from w in grouping.DefaultIfEmpty()
select new { SquadName = s.Name, WeaponName = Maybe(w, () => w.Name) },
elementSorter: e => e.SquadName + " " + e.WeaponName);
}

[ConditionalFact]
public virtual async Task Include_with_group_by_on_entity_qsre()
{
using (var ctx = CreateContext())
{
var query = ctx.Squads.Include(s => s.Members).GroupBy(s => s);
var results = await query.ToListAsync();

foreach (var result in results)
{
foreach (var grouping in result)
{
Assert.True(grouping.Members.Count > 0);
}
}
}
}

[ConditionalFact]
public virtual async Task Include_with_group_by_on_entity_qsre_with_composite_key()
{
using (var ctx = CreateContext())
{
var query = ctx.Gears.Include(g => g.Weapons).GroupBy(g => g);
var results = await query.ToListAsync();

foreach (var result in results)
{
foreach (var grouping in result)
{
Assert.True(grouping.Weapons.Count > 0);
}
}
}
}

[ConditionalFact]
public virtual async Task Include_with_group_by_on_entity_navigation()
{
using (var ctx = CreateContext())
{
var query = ctx.Factions.OfType<LocustHorde>().Include(lh => lh.Leaders).GroupBy(lh => lh.Commander.DefeatedBy);
var results = await query.ToListAsync();

foreach (var result in results)
{
foreach (var grouping in result)
{
Assert.True(grouping.Leaders.Count > 0);
}
}
}
}
}
}
183 changes: 183 additions & 0 deletions src/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4365,6 +4365,189 @@ public virtual void Negated_bool_ternary_inside_anonymous_type_in_projection()
elementSorter: e => e.c);
}

[ConditionalFact]
public virtual void Order_by_entity_qsre()
{
AssertQuery<Gear>(
gs => gs.OrderBy(g => g.AssignedCity).ThenByDescending(g => g.Nickname).Select(f => f.FullName),
gs => gs.OrderBy(g => Maybe(g.AssignedCity, () => g.AssignedCity.Name)).ThenByDescending(g => g.Nickname).Select(f => f.FullName),
assertOrder: true);
}

[ConditionalFact]
public virtual void Order_by_entity_qsre_with_inheritance()
{
AssertQuery<LocustLeader>(
lls => lls.OfType<LocustCommander>().OrderBy(lc => lc.HighCommand).ThenBy(lc => lc.Name).Select(lc => lc.Name),
assertOrder: true);
}

[ConditionalFact]
public virtual void Order_by_entity_qsre_composite_key()
{
AssertQuery<Weapon>(
ws => ws.OrderBy(w => w.Owner).Select(w => w.Name),
ws => ws.OrderBy(w => Maybe(w.Owner, () => w.Owner.Nickname)).ThenBy(w => MaybeScalar<int>(w.Owner, () => w.Owner.SquadId)).Select(w => w.Name),
assertOrder: true);
}

[ConditionalFact]
public virtual void Order_by_entity_qsre_with_other_orderbys()
{
AssertQuery<Weapon>(
ws => ws.OrderBy(w => w.IsAutomatic).ThenByDescending(w => w.Owner).ThenBy(w => w.SynergyWith).ThenBy(w => w.Name),
ws => ws
.OrderBy(w => w.IsAutomatic)
.ThenByDescending(w => Maybe(w.Owner, () => w.Owner.Nickname))
.ThenByDescending(w => MaybeScalar<int>(w.Owner, () => w.Owner.SquadId))
.ThenBy(w => MaybeScalar<int>(w.SynergyWith, () => w.SynergyWith.Id))
.ThenBy(w => w.Name));
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys()
{
AssertQuery<Weapon>(
ws => from w1 in ws
join w2 in ws on w1 equals w2
select new { Name1 = w1.Name, Name2 = w2.Name },
elementSorter: e => e.Name1 + " " + e.Name2);
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys_composite_key()
{
AssertQuery<Gear>(
gs => from g1 in gs
join g2 in gs on g1 equals g2
select new { GearName1 = g1.FullName, GearName2 = g2.FullName },
elementSorter: e => e.GearName1 + " " + e.GearName2);
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys_inheritance()
{
AssertQuery<Gear>(
gs => from g in gs
join o in gs.OfType<Officer>() on g equals o
select new { GearName = g.FullName, OfficerName = o.FullName },
elementSorter: e => e.GearName + " " + e.OfficerName);
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys_outer_key_is_navigation()
{
AssertQuery<Weapon>(
ws => from w1 in ws
join w2 in ws on w1.SynergyWith equals w2
select new { Name1 = w1.Name, Name2 = w2.Name },
elementSorter: e => e.Name1 + " " + e.Name2);
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys_inner_key_is_navigation()
{
AssertQuery<City, Gear>(
(cs, gs) =>
from c in cs
join g in gs on c equals g.AssignedCity
select new { CityName = c.Name, GearNickname = g.Nickname },
e => e.CityName + " " + e.GearNickname);
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys_inner_key_is_navigation_composite_key()
{
AssertQuery<Gear, CogTag>(
(gs, ts) =>
from g in gs
join t in ts.Where(tt => tt.Note == "Cole's Tag" || tt.Note == "Dom's Tag") on g equals t.Gear
select new { g.Nickname, t.Note },
elementSorter: e => e.Nickname + " " + e.Note);
}

[ConditionalFact]
public virtual void Join_on_entity_qsre_keys_inner_key_is_nested_navigation()
{
AssertQuery<Squad, Weapon>(
(ss, ws) =>
from s in ss
join w in ws.Where(ww => ww.IsAutomatic) on s equals w.Owner.Squad
select new { SquadName = s.Name, WeaponName = w.Name },
elementSorter: e => e.SquadName + " " + e.WeaponName);
}

[ConditionalFact]
public virtual void GroupJoin_on_entity_qsre_keys_inner_key_is_nested_navigation()
{
AssertQuery<Squad, Weapon>(
(ss, ws) =>
from s in ss
join w in ws on s equals w.Owner.Squad into grouping
from w in grouping.DefaultIfEmpty()
select new { SquadName = s.Name, WeaponName = w.Name },
(ss, ws) =>
from s in ss
join w in ws on s equals Maybe(w.Owner, () => w.Owner.Squad) into grouping
from w in grouping.DefaultIfEmpty()
select new { SquadName = s.Name, WeaponName = Maybe(w, () => w.Name) },
elementSorter: e => e.SquadName + " " + e.WeaponName);
}

[ConditionalFact]
public virtual void Include_with_group_by_on_entity_qsre()
{
using (var ctx = CreateContext())
{
var query = ctx.Squads.Include(s => s.Members).GroupBy(s => s);
var results = query.ToList();

foreach (var result in results)
{
foreach (var grouping in result)
{
Assert.True(grouping.Members.Count > 0);
}
}
}
}

[ConditionalFact]
public virtual void Include_with_group_by_on_entity_qsre_with_composite_key()
{
using (var ctx = CreateContext())
{
var query = ctx.Gears.Include(g => g.Weapons).GroupBy(g => g);
var results = query.ToList();

foreach (var result in results)
{
foreach (var grouping in result)
{
Assert.True(grouping.Weapons.Count > 0);
}
}
}
}

[ConditionalFact]
public virtual void Include_with_group_by_on_entity_navigation()
{
using (var ctx = CreateContext())
{
var query = ctx.Factions.OfType<LocustHorde>().Include(lh => lh.Leaders).GroupBy(lh => lh.Commander.DefeatedBy);
var results = query.ToList();

foreach (var result in results)
{
foreach (var grouping in result)
{
Assert.True(grouping.Leaders.Count > 0);
}
}
}
}

// Remember to add any new tests to Async version of this test class

protected GearsOfWarContext CreateContext() => Fixture.CreateContext();
Expand Down
Loading