diff --git a/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs index be2004b91e0..5263946bc5b 100644 --- a/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/ComplexNavigationsQueryTestBase.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.TestModels.ComplexNavigationsModel; using Microsoft.EntityFrameworkCore.TestUtilities; @@ -5492,5 +5493,29 @@ public virtual Task Nested_object_constructed_from_group_key_properties(bool asy Aggregate = g.Sum(x => x.Name.Length) })); } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupBy_aggregate_where_required_relationship(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .GroupBy(l2 => l2.OneToMany_Required_Inverse2.Id) + .Select(g => new { g.Key, Max = g.Max(e => e.Id) }) + .Where(x => x.Max != 2)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupBy_aggregate_where_required_relationship_2(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .GroupBy(l2 => l2.OneToMany_Required_Inverse2.Id) + .Select(g => new { g.Key, Max = g.Max(e => e.Id) }) + .Where(x => x.Max < 2 || x.Max > 2)); + } } } diff --git a/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs index 8e6d07c6a2d..a0b193d6f19 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindGroupByQueryTestBase.cs @@ -2166,6 +2166,45 @@ public virtual Task GroupBy_let_orderby_projection_with_coalesce_operation(bool })); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupBy_Min_Where_optional_relationship(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .GroupBy(o => o.Customer.CustomerID) + .Select(g => new { g.Key, Count = g.Count() }) + .Where(x => x.Count != 2)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupBy_Min_Where_optional_relationship_2(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .GroupBy(o => o.Customer.CustomerID) + .Select(g => new { g.Key, Count = g.Count() }) + .Where(x => x.Count < 2 || x.Count > 2)); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task GroupBy_aggregate_over_a_subquery(bool async) + { + return AssertQuery( + async, + ss => ss.Set() + .GroupBy(o => o.CustomerID) + .Select(g => new + { + g.Key, + Count = (from c in ss.Set() where c.CustomerID == g.Key select c).Count() + })); + } + #endregion #region GroupByWithoutAggregate diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs index 3497a5c4b45..b38cae0d82c 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs @@ -5775,6 +5775,30 @@ WHERE [l0].[Id] IS NOT NULL GROUP BY [l].[Id], [l].[Date], [l].[Name], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l1].[Name]"); } + public override async Task GroupBy_aggregate_where_required_relationship(bool async) + { + await base.GroupBy_aggregate_where_required_relationship(async); + + AssertSql( + @"SELECT [l0].[Id] AS [Key], MAX([l].[Id]) AS [Max] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelOne] AS [l0] ON [l].[OneToMany_Required_Inverse2Id] = [l0].[Id] +GROUP BY [l0].[Id] +HAVING (MAX([l].[Id]) <> 2) OR MAX([l].[Id]) IS NULL"); + } + + public override async Task GroupBy_aggregate_where_required_relationship_2(bool async) + { + await base.GroupBy_aggregate_where_required_relationship_2(async); + + AssertSql( + @"SELECT [l0].[Id] AS [Key], MAX([l].[Id]) AS [Max] +FROM [LevelTwo] AS [l] +INNER JOIN [LevelOne] AS [l0] ON [l].[OneToMany_Required_Inverse2Id] = [l0].[Id] +GROUP BY [l0].[Id] +HAVING (MAX([l].[Id]) < 2) OR (MAX([l].[Id]) > 2)"); + } + private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs index ea4ab0f54f0..9ac442862a9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindGroupByQuerySqlServerTest.cs @@ -1886,6 +1886,50 @@ GROUP BY [c].[City] ORDER BY COUNT(*) DESC, [c].[City]"); } + public override async Task GroupBy_let_orderby_projection_with_coalesce_operation(bool async) + { + await base.GroupBy_let_orderby_projection_with_coalesce_operation(async); + + AssertSql(" "); + } + + public override async Task GroupBy_Min_Where_optional_relationship(bool async) + { + await base.GroupBy_Min_Where_optional_relationship(async); + + AssertSql( + @"SELECT [c].[CustomerID] AS [Key], COUNT(*) AS [Count] +FROM [Orders] AS [o] +LEFT JOIN [Customers] AS [c] ON [o].[CustomerID] = [c].[CustomerID] +GROUP BY [c].[CustomerID] +HAVING COUNT(*) <> 2"); + } + + public override async Task GroupBy_Min_Where_optional_relationship_2(bool async) + { + await base.GroupBy_Min_Where_optional_relationship_2(async); + + AssertSql( + @"SELECT [c].[CustomerID] AS [Key], COUNT(*) AS [Count] +FROM [Orders] AS [o] +LEFT JOIN [Customers] AS [c] ON [o].[CustomerID] = [c].[CustomerID] +GROUP BY [c].[CustomerID] +HAVING (COUNT(*) < 2) OR (COUNT(*) > 2)"); + } + + public override async Task GroupBy_aggregate_over_a_subquery(bool async) + { + await base.GroupBy_aggregate_over_a_subquery(async); + + AssertSql( + @"SELECT [o].[CustomerID] AS [Key], ( + SELECT COUNT(*) + FROM [Customers] AS [c] + WHERE [c].[CustomerID] = [o].[CustomerID]) AS [Count] +FROM [Orders] AS [o] +GROUP BY [o].[CustomerID]"); + } + public override async Task GroupBy_with_grouping_key_using_Like(bool async) { await base.GroupBy_with_grouping_key_using_Like(async);