diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs b/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs index 65ac4359aa0..a0c69a1f457 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs @@ -865,5 +865,17 @@ public override Task Project_non_nullable_value_after_FirstOrDefault_on_empty_co { return base.Project_non_nullable_value_after_FirstOrDefault_on_empty_collection(isAsync); } + + [ConditionalTheory(Skip = "Issue#17246")] + public override Task Filtered_collection_projection_is_tracked(bool isAsync) + { + return base.Filtered_collection_projection_is_tracked(isAsync); + } + + [ConditionalTheory(Skip = "Issue#17246")] + public override Task Filtered_collection_projection_with_to_list_is_tracked(bool isAsync) + { + return base.Filtered_collection_projection_with_to_list_is_tracked(isAsync); + } } } diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs index 860b1761fc5..d8549ada1d8 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs @@ -1258,5 +1258,55 @@ public override bool Equals(object obj) public override int GetHashCode() => HashCode.Combine(Id, City); } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Filtered_collection_projection_is_tracked(bool isAsync) + { + using (var context = CreateContext()) + { + var query = context.Customers + .Where(c => c.CustomerID.StartsWith("A")) + .Select(c => + new + { + Customer = c, + FilteredOrders = c.Orders.Where(o => o.OrderID > 11000) + }); + + var result = isAsync + ? (await query.ToListAsync()) + : query.ToList(); + + Assert.Equal(4, result.Count); + Assert.True(result.All(r => (r.Customer.Orders?.Count ?? 0) == r.FilteredOrders.Count())); + Assert.Equal(6, context.ChangeTracker.Entries().Count()); + } + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Filtered_collection_projection_with_to_list_is_tracked(bool isAsync) + { + using (var context = CreateContext()) + { + var query = context.Customers + .Where(c => c.CustomerID.StartsWith("A")) + .Select(c => + new + { + Customer = c, + FilteredOrders = c.Orders.Where(o => o.OrderID > 11000).ToList() + }); + + var result = isAsync + ? (await query.ToListAsync()) + : query.ToList(); + + Assert.Equal(4, result.Count); + Assert.True(result.All(r => (r.Customer.Orders?.Count ?? 0) == r.FilteredOrders.Count)); + Assert.Equal(6, context.ChangeTracker.Entries().Count()); + } + } } } diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs index 6ef7d73a594..07057d77214 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs @@ -1033,5 +1033,37 @@ public override async Task Member_binding_after_ctor_arguments_fails_with_client (await Assert.ThrowsAsync( () => base.Member_binding_after_ctor_arguments_fails_with_client_eval(isAsync))).Message)); } + + public override async Task Filtered_collection_projection_is_tracked(bool isAsync) + { + await base.Filtered_collection_projection_is_tracked(isAsync); + + AssertSql( + @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate] +FROM [Customers] AS [c] +LEFT JOIN ( + SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] + FROM [Orders] AS [o] + WHERE [o].[OrderID] > 11000 +) AS [t] ON [c].[CustomerID] = [t].[CustomerID] +WHERE [c].[CustomerID] LIKE N'A%' +ORDER BY [c].[CustomerID], [t].[OrderID]"); + } + + public override async Task Filtered_collection_projection_with_to_list_is_tracked(bool isAsync) + { + await base.Filtered_collection_projection_with_to_list_is_tracked(isAsync); + + AssertSql( + @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate] +FROM [Customers] AS [c] +LEFT JOIN ( + SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] + FROM [Orders] AS [o] + WHERE [o].[OrderID] > 11000 +) AS [t] ON [c].[CustomerID] = [t].[CustomerID] +WHERE [c].[CustomerID] LIKE N'A%' +ORDER BY [c].[CustomerID], [t].[OrderID]"); + } } }