diff --git a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs index d853af6543b..2d7c9cedd7e 100644 --- a/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs @@ -1196,6 +1196,36 @@ from t2 in ss.Set() AssertEqual(e.t2, e.t2); }); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Conditional_Navigation_With_Trivial_Member_Access(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(g => (g.AssignedCity != null ? g.AssignedCity : g.CityOfBirth).Name != "Ephyra") + .Select(g => new { g.Nickname }), + elementSorter: e => e.Nickname); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Conditional_Navigation_With_Member_Access_On_Same_Type(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(g => (g.AssignedCity != null ? g.AssignedCity : g.CityOfBirth).Nation == "Tyrus") + .Select(g => new { g.Nickname, g.FullName }), + elementSorter: e => e.Nickname); + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Conditional_Navigation_With_Member_Access_On_Related_Types(bool async) + => AssertQuery( + async, + ss => ss.Set() + .Where(g => (g.DeputyCommander != null ? g.DeputyCommander : g.Commander).ThreatLevel == 4) + .Select(g => new { g.Name }), + elementSorter: e => e.Name); + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Singleton_Navigation_With_Member_Access(bool async) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs index 25a9a09dd29..cb05b1326e3 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs @@ -992,6 +992,61 @@ CROSS JOIN [Tags] AS [t0] """); } + public override async Task Conditional_Navigation_With_Trivial_Member_Access(bool async) + { + await base.Conditional_Navigation_With_Trivial_Member_Access(async); + + AssertSql( + """ +SELECT [g].[Nickname] +FROM [Gears] AS [g] +LEFT JOIN [Cities] AS [c] ON [g].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] AS [c0] ON [g].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Name] + ELSE [c0].[Name] +END <> N'Ephyra' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Same_Type(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Same_Type(async); + + AssertSql( + """ +SELECT [g].[Nickname], [g].[FullName] +FROM [Gears] AS [g] +LEFT JOIN [Cities] AS [c] ON [g].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] AS [c0] ON [g].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Nation] + ELSE [c0].[Nation] +END = N'Tyrus' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Related_Types(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Related_Types(async); + + AssertSql( + """ +SELECT [f].[Name] +FROM [Factions] AS [f] +LEFT JOIN [LocustLeaders] AS [l] ON [f].[DeputyCommanderName] = [l].[Name] +LEFT JOIN ( + SELECT [l0].[Name], [l0].[ThreatLevel] + FROM [LocustLeaders] AS [l0] + WHERE [l0].[Discriminator] = N'LocustCommander' +) AS [l1] ON [f].[CommanderName] = [l1].[Name] +WHERE CASE + WHEN [l].[Name] IS NOT NULL THEN [l].[ThreatLevel] + ELSE [l1].[ThreatLevel] +END = CAST(4 AS smallint) +"""); + } + public override async Task Select_Singleton_Navigation_With_Member_Access(bool async) { await base.Select_Singleton_Navigation_With_Member_Access(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs index 3d6841cc833..0bf0b574d67 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel; @@ -1366,6 +1366,75 @@ FROM [Officers] AS [o0] """); } + public override async Task Conditional_Navigation_With_Trivial_Member_Access(bool async) + { + await base.Conditional_Navigation_With_Trivial_Member_Access(async); + + AssertSql( + """ +SELECT [u].[Nickname] +FROM ( + SELECT [g].[Nickname], [g].[AssignedCityName], [g].[CityOfBirthName] + FROM [Gears] AS [g] + UNION ALL + SELECT [o].[Nickname], [o].[AssignedCityName], [o].[CityOfBirthName] + FROM [Officers] AS [o] +) AS [u] +LEFT JOIN [Cities] AS [c] ON [u].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] AS [c0] ON [u].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Name] + ELSE [c0].[Name] +END <> N'Ephyra' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Same_Type(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Same_Type(async); + + AssertSql( + """ +SELECT [u].[Nickname], [u].[FullName] +FROM ( + SELECT [g].[Nickname], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName] + FROM [Gears] AS [g] + UNION ALL + SELECT [o].[Nickname], [o].[AssignedCityName], [o].[CityOfBirthName], [o].[FullName] + FROM [Officers] AS [o] +) AS [u] +LEFT JOIN [Cities] AS [c] ON [u].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] AS [c0] ON [u].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Nation] + ELSE [c0].[Nation] +END = N'Tyrus' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Related_Types(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Related_Types(async); + + AssertSql( + """ +SELECT [l].[Name] +FROM [LocustHordes] AS [l] +LEFT JOIN ( + SELECT [l0].[Name], [l0].[ThreatLevel] + FROM [LocustLeaders] AS [l0] + UNION ALL + SELECT [l1].[Name], [l1].[ThreatLevel] + FROM [LocustCommanders] AS [l1] +) AS [u] ON [l].[DeputyCommanderName] = [u].[Name] +LEFT JOIN [LocustCommanders] AS [l2] ON [l].[CommanderName] = [l2].[Name] +WHERE CASE + WHEN [u].[Name] IS NOT NULL THEN [u].[ThreatLevel] + ELSE [l2].[ThreatLevel] +END = CAST(4 AS smallint) +"""); + } + public override async Task Select_Singleton_Navigation_With_Member_Access(bool async) { await base.Select_Singleton_Navigation_With_Member_Access(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs index 74dc6a12c30..7f54d52461d 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs @@ -1184,6 +1184,65 @@ FROM [Gears] AS [g0] """); } + public override async Task Conditional_Navigation_With_Trivial_Member_Access(bool async) + { + await base.Conditional_Navigation_With_Trivial_Member_Access(async); + + AssertSql( + """ +SELECT [g].[Nickname] +FROM [Gears] AS [g] +LEFT JOIN [Cities] AS [c] ON [g].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] AS [c0] ON [g].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Name] + ELSE [c0].[Name] +END <> N'Ephyra' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Same_Type(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Same_Type(async); + + AssertSql( + """ +SELECT [g].[Nickname], [g].[FullName] +FROM [Gears] AS [g] +LEFT JOIN [Cities] AS [c] ON [g].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] AS [c0] ON [g].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Nation] + ELSE [c0].[Nation] +END = N'Tyrus' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Related_Types(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Related_Types(async); + + AssertSql( + """ +SELECT [f].[Name] +FROM [Factions] AS [f] +INNER JOIN [LocustHordes] AS [l] ON [f].[Id] = [l].[Id] +LEFT JOIN ( + SELECT [l0].[Name], [l0].[ThreatLevel] + FROM [LocustLeaders] AS [l0] +) AS [s] ON [l].[DeputyCommanderName] = [s].[Name] +LEFT JOIN ( + SELECT [l1].[Name], [l1].[ThreatLevel] + FROM [LocustLeaders] AS [l1] + INNER JOIN [LocustCommanders] AS [l2] ON [l1].[Name] = [l2].[Name] +) AS [s0] ON [l].[CommanderName] = [s0].[Name] +WHERE CASE + WHEN [s].[Name] IS NOT NULL THEN [s].[ThreatLevel] + ELSE [s0].[ThreatLevel] +END = CAST(4 AS smallint) +"""); + } + public override async Task Select_Singleton_Navigation_With_Member_Access(bool async) { await base.Select_Singleton_Navigation_With_Member_Access(async); diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs index e8d3095c438..a7efceddf89 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.SqlServer.Internal; @@ -2482,6 +2482,61 @@ LEFT JOIN ( """); } + public override async Task Conditional_Navigation_With_Trivial_Member_Access(bool async) + { + await base.Conditional_Navigation_With_Trivial_Member_Access(async); + + AssertSql( + """ +SELECT [g].[Nickname] +FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] +LEFT JOIN [Cities] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [c] ON [g].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [c0] ON [g].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Name] + ELSE [c0].[Name] +END <> N'Ephyra' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Same_Type(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Same_Type(async); + + AssertSql( + """ +SELECT [g].[Nickname], [g].[FullName] +FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g] +LEFT JOIN [Cities] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [c] ON [g].[AssignedCityName] = [c].[Name] +INNER JOIN [Cities] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [c0] ON [g].[CityOfBirthName] = [c0].[Name] +WHERE CASE + WHEN [c].[Name] IS NOT NULL THEN [c].[Nation] + ELSE [c0].[Nation] +END = N'Tyrus' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Related_Types(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Related_Types(async); + + AssertSql( + """ +SELECT [f].[Name] +FROM [Factions] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [f] +LEFT JOIN [LocustLeaders] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l] ON [f].[DeputyCommanderName] = [l].[Name] +LEFT JOIN ( + SELECT [l0].[Name], [l0].[ThreatLevel] + FROM [LocustLeaders] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [l0] + WHERE [l0].[Discriminator] = N'LocustCommander' +) AS [l1] ON [f].[CommanderName] = [l1].[Name] +WHERE CASE + WHEN [l].[Name] IS NOT NULL THEN [l].[ThreatLevel] + ELSE [l1].[ThreatLevel] +END = CAST(4 AS smallint) +"""); + } + public override async Task Select_Singleton_Navigation_With_Member_Access(bool async) { await base.Select_Singleton_Navigation_With_Member_Access(async); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs index 7ae8d109ba7..f4fc0458189 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs @@ -7766,6 +7766,61 @@ CROSS JOIN "Tags" AS "t0" """); } + public override async Task Conditional_Navigation_With_Trivial_Member_Access(bool async) + { + await base.Conditional_Navigation_With_Trivial_Member_Access(async); + + AssertSql( + """ +SELECT "g"."Nickname" +FROM "Gears" AS "g" +LEFT JOIN "Cities" AS "c" ON "g"."AssignedCityName" = "c"."Name" +INNER JOIN "Cities" AS "c0" ON "g"."CityOfBirthName" = "c0"."Name" +WHERE CASE + WHEN "c"."Name" IS NOT NULL THEN "c"."Name" + ELSE "c0"."Name" +END <> 'Ephyra' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Same_Type(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Same_Type(async); + + AssertSql( + """ +SELECT "g"."Nickname", "g"."FullName" +FROM "Gears" AS "g" +LEFT JOIN "Cities" AS "c" ON "g"."AssignedCityName" = "c"."Name" +INNER JOIN "Cities" AS "c0" ON "g"."CityOfBirthName" = "c0"."Name" +WHERE CASE + WHEN "c"."Name" IS NOT NULL THEN "c"."Nation" + ELSE "c0"."Nation" +END = 'Tyrus' +"""); + } + + public override async Task Conditional_Navigation_With_Member_Access_On_Related_Types(bool async) + { + await base.Conditional_Navigation_With_Member_Access_On_Related_Types(async); + + AssertSql( + """ +SELECT "f"."Name" +FROM "Factions" AS "f" +LEFT JOIN "LocustLeaders" AS "l" ON "f"."DeputyCommanderName" = "l"."Name" +LEFT JOIN ( + SELECT "l0"."Name", "l0"."ThreatLevel" + FROM "LocustLeaders" AS "l0" + WHERE "l0"."Discriminator" = 'LocustCommander' +) AS "l1" ON "f"."CommanderName" = "l1"."Name" +WHERE CASE + WHEN "l"."Name" IS NOT NULL THEN "l"."ThreatLevel" + ELSE "l1"."ThreatLevel" +END = 4 +"""); + } + public override async Task Complex_GroupBy_after_set_operator_using_result_selector(bool async) { await base.Complex_GroupBy_after_set_operator_using_result_selector(async);