diff --git a/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs b/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs index 6606a28f279..77280a56cba 100644 --- a/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs +++ b/src/EFCore/Query/Internal/EntityEqualityRewritingExpressionVisitor.cs @@ -127,6 +127,11 @@ protected override Expression VisitMemberInit(MemberInitExpression memberInitExp } } + // Note that we could bubble up entity type information from the expressions initializing the array. However, EF Core doesn't + // actually support doing much further with this array, so it's not worth the complexity (right now). So we simply unwrap. + protected override Expression VisitNewArray(NewArrayExpression newArrayExpression) + => newArrayExpression.Update(Visit(newArrayExpression.Expressions).Select(Unwrap)); + protected override Expression VisitMember(MemberExpression memberExpression) { var visitedExpression = base.Visit(memberExpression.Expression); diff --git a/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs b/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs index c2e4f13045d..3cfaca4f489 100644 --- a/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs +++ b/test/EFCore.Cosmos.FunctionalTests/Query/SimpleQueryCosmosTest.Select.cs @@ -83,6 +83,29 @@ FROM root c WHERE ((c[""Discriminator""] = ""Employee"") AND (c[""EmployeeID""] = 1))"); } + [ConditionalTheory(Skip = "Issue#17246")] + public override async Task Projection_of_entity_type_into_object_array(bool isAsync) + { + await base.Projection_of_entity_type_into_object_array(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""] +FROM root c +WHERE ((c[""Discriminator""] = ""Employee"") AND c[""CustomerID""] LIKE N'A%' +ORDER BY c[""CustomerID""]"); + } + + [ConditionalTheory(Skip = "Issue#17246")] + public override async Task Projection_of_multiple_entity_types_into_object_array(bool isAsync) + { + await base.Projection_of_multiple_entity_types_into_object_array(isAsync); + + AssertSql( + @"SELECT c +FROM root c +WHERE (c[""Discriminator""] = ""Customer"")"); + } + public override async Task Project_to_int_array(bool isAsync) { await base.Project_to_int_array(isAsync); diff --git a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs index 89a745e69aa..3e6ecfc2046 100644 --- a/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs +++ b/test/EFCore.Specification.Tests/Query/SimpleQueryTestBase.Select.cs @@ -66,6 +66,30 @@ public virtual Task Project_to_object_array(bool isAsync) elementAsserter: (e, a) => AssertArrays(e, a, 3)); } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Projection_of_entity_type_into_object_array(bool isAsync) + { + return AssertQuery( + isAsync, + ss => ss.Set().OrderBy(c => c.CustomerID).Where(c => c.CustomerID.StartsWith("A")) + .Select(c => new object[] { c }), + entryCount: 4, + assertOrder: true); + } + + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Projection_of_multiple_entity_types_into_object_array(bool isAsync) + { + return AssertQuery( + isAsync, + ss => ss.Set().OrderBy(o => o.OrderID).Where(o => o.OrderID < 10300) + .Select(o => new object[] { o, o.Customer }), + entryCount: 87, + assertOrder: true); + } + [ConditionalTheory] [MemberData(nameof(IsAsyncData))] public virtual Task Project_to_int_array(bool isAsync) diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs index de6d1a5f62c..6dfc3fad776 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/SimpleQuerySqlServerTest.Select.cs @@ -79,6 +79,29 @@ FROM [Employees] AS [e] WHERE [e].[EmployeeID] = 1"); } + public override async Task Projection_of_entity_type_into_object_array(bool isAsync) + { + await base.Projection_of_entity_type_into_object_array(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] +FROM [Customers] AS [c] +WHERE [c].[CustomerID] LIKE N'A%' +ORDER BY [c].[CustomerID]"); + } + + public override async Task Projection_of_multiple_entity_types_into_object_array(bool isAsync) + { + await base.Projection_of_multiple_entity_types_into_object_array(isAsync); + + AssertSql( + @"SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] +FROM [Orders] AS [o] +LEFT JOIN [Customers] AS [c] ON [o].[CustomerID] = [c].[CustomerID] +WHERE [o].[OrderID] < 10300 +ORDER BY [o].[OrderID]"); + } + public override async Task Project_to_int_array(bool isAsync) { await base.Project_to_int_array(isAsync);