diff --git a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
index 76bae79b2c8..bdf1082a24a 100644
--- a/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
+++ b/src/EFCore.Relational/Properties/RelationalStrings.Designer.cs
@@ -1,4 +1,4 @@
-//
+//
using System;
using System.Reflection;
@@ -1113,6 +1113,14 @@ public static string UnsupportedOperatorForSqlExpression([CanBeNull] object node
public static string VisitChildrenMustBeOverridden
=> GetString("VisitChildrenMustBeOverridden");
+ ///
+ /// The query has been configured to use '{splitQueryEnumValue}' and contains a collection in the 'Select' call, which could not be split into separate query. Please remove '{splitQueryMethodName}' if applied or add '{singleQueryMethodName}' to the query.
+ ///
+ public static string UnableToSplitCollectionProjectionInSplitQuery([CanBeNull] object splitQueryEnumValue, [CanBeNull] object splitQueryMethodName, [CanBeNull] object singleQueryMethodName)
+ => string.Format(
+ GetString("UnableToSplitCollectionProjectionInSplitQuery", nameof(splitQueryEnumValue), nameof(splitQueryMethodName), nameof(singleQueryMethodName)),
+ splitQueryEnumValue, splitQueryMethodName, singleQueryMethodName);
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/EFCore.Relational/Properties/RelationalStrings.resx b/src/EFCore.Relational/Properties/RelationalStrings.resx
index ed2e18a3359..ca162da6e51 100644
--- a/src/EFCore.Relational/Properties/RelationalStrings.resx
+++ b/src/EFCore.Relational/Properties/RelationalStrings.resx
@@ -1,17 +1,17 @@
-
@@ -765,4 +765,7 @@
VisitChildren must be overridden in class deriving from SqlExpression.
+
+ The query has been configured to use '{splitQueryEnumValue}' and contains a collection in the 'Select' call, which could not be split into separate query. Please remove '{splitQueryMethodName}' if applied or add '{singleQueryMethodName}' to the query.
+
\ No newline at end of file
diff --git a/src/EFCore.Relational/Query/Internal/CollectionJoinApplyingExpressionVisitor.cs b/src/EFCore.Relational/Query/Internal/CollectionJoinApplyingExpressionVisitor.cs
index 34c4d1d1bc3..6d8617c0252 100644
--- a/src/EFCore.Relational/Query/Internal/CollectionJoinApplyingExpressionVisitor.cs
+++ b/src/EFCore.Relational/Query/Internal/CollectionJoinApplyingExpressionVisitor.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using System.Linq.Expressions;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Diagnostics;
@@ -68,36 +69,26 @@ protected override Expression VisitExtension(Expression extensionExpression)
selectExpression.PushdownIntoSubquery();
}
- if (_splitQuery)
- {
- var splitCollectionShaperExpression = (RelationalSplitCollectionShaperExpression)selectExpression.ApplyCollectionJoin(
- projectionBindingExpression.Index.Value,
- collectionId,
- collectionShaperExpression.InnerShaper,
- collectionShaperExpression.Navigation,
- collectionShaperExpression.ElementType,
- _splitQuery);
+ var innerShaper = Visit(collectionShaperExpression.InnerShaper);
- var innerShaper = Visit(splitCollectionShaperExpression.InnerShaper);
+ var collectionJoin = selectExpression.ApplyCollectionJoin(
+ projectionBindingExpression.Index.Value,
+ collectionId,
+ innerShaper,
+ collectionShaperExpression.Navigation,
+ collectionShaperExpression.ElementType,
+ _splitQuery);
- return splitCollectionShaperExpression.Update(
- splitCollectionShaperExpression.ParentIdentifier,
- splitCollectionShaperExpression.ChildIdentifier,
- splitCollectionShaperExpression.SelectExpression,
- innerShaper);
- }
- else
+ if (_splitQuery
+ && collectionJoin == null)
{
- var innerShaper = Visit(collectionShaperExpression.InnerShaper);
-
- return selectExpression.ApplyCollectionJoin(
- projectionBindingExpression.Index.Value,
- collectionId,
- innerShaper,
- collectionShaperExpression.Navigation,
- collectionShaperExpression.ElementType,
- _splitQuery);
+ throw new InvalidOperationException(RelationalStrings.UnableToSplitCollectionProjectionInSplitQuery(
+ $"{nameof(QuerySplittingBehavior)}.{QuerySplittingBehavior.SplitQuery}",
+ nameof(RelationalQueryableExtensions.AsSplitQuery),
+ nameof(RelationalQueryableExtensions.AsSingleQuery)));
}
+
+ return collectionJoin;
}
return extensionExpression is ShapedQueryExpression shapedQueryExpression
diff --git a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
index 2dd9808b9ee..37b741822a2 100644
--- a/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
+++ b/src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
@@ -1330,6 +1330,13 @@ public Expression ApplyCollectionJoin(
if (splitQuery)
{
+ var containsReferenceToOuter = new SelectExpressionCorrelationFindingExpressionVisitor(this)
+ .ContainsOuterReference(innerSelectExpression);
+ if (containsReferenceToOuter)
+ {
+ return null;
+ }
+
var parentIdentifier = GetIdentifierAccessor(_identifier).Item1;
innerSelectExpression.ApplyProjection();
diff --git a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs
index ce923b09bd4..7fccc22d82b 100644
--- a/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs
+++ b/test/EFCore.Relational.Specification.Tests/Query/ComplexNavigationsQueryRelationalTestBase.cs
@@ -4,6 +4,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.TestModels.ComplexNavigationsModel;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;
@@ -482,6 +483,51 @@ public virtual async Task Filtered_include_calling_methods_directly_on_parameter
.AsSplitQuery()))).Message;
}
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual async Task Projecting_collection_with_FirstOrDefault_split_throws(bool async)
+ {
+ Assert.Equal(
+ RelationalStrings.UnableToSplitCollectionProjectionInSplitQuery(
+ "QuerySplittingBehavior.SplitQuery", "AsSplitQuery", "AsSingleQuery"),
+ (await Assert.ThrowsAsync(
+ () => AssertFirstOrDefault(
+ async,
+ ss => ss.Set()
+ .AsSplitQuery()
+ .Select(e => new
+ {
+ e.Id,
+ Level2s = e.OneToMany_Optional1.ToList()
+ }),
+ predicate: l => l.Id == 1,
+ asserter: (e, a) =>
+ {
+ Assert.Equal(e.Id, a.Id);
+ AssertCollection(e.Level2s, a.Level2s);
+ }))).Message);
+ }
+
+ [ConditionalTheory]
+ [MemberData(nameof(IsAsyncData))]
+ public virtual Task Projecting_collection_with_FirstOrDefault_without_split_works(bool async)
+ {
+ return AssertFirstOrDefault(
+ async,
+ ss => ss.Set()
+ .Select(e => new
+ {
+ e.Id,
+ Level2s = e.OneToMany_Optional1.ToList()
+ }),
+ predicate: l => l.Id == 1,
+ asserter: (e, a) =>
+ {
+ Assert.Equal(e.Id, a.Id);
+ AssertCollection(e.Level2s, a.Level2s);
+ });
+ }
+
protected virtual bool CanExecuteQueryString => false;
protected override QueryAsserter CreateQueryAsserter(TFixture fixture)
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs
index 05e0837d1d8..ac099482ab0 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs
@@ -5087,7 +5087,7 @@ FROM [LevelTwo] AS [l0]
) AS [t]
WHERE 0 < [t].[row]
) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id]
-ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t0].[Id]",
+ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name]",
//
@"SELECT [t2].[Id], [t2].[Level2_Optional_Id], [t2].[Level2_Required_Id], [t2].[Name], [t2].[OneToMany_Optional_Inverse3Id], [t2].[OneToMany_Optional_Self_Inverse3Id], [t2].[OneToMany_Required_Inverse3Id], [t2].[OneToMany_Required_Self_Inverse3Id], [t2].[OneToOne_Optional_PK_Inverse3Id], [t2].[OneToOne_Optional_Self3Id], [l].[Id], [t0].[Id]
FROM [LevelOne] AS [l]
@@ -5107,7 +5107,7 @@ FROM [LevelThree] AS [l1]
) AS [t1]
WHERE 0 < [t1].[row]
) AS [t2] ON [t0].[Id] = [t2].[OneToMany_Optional_Inverse3Id]
-ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t0].[Id], [t2].[OneToMany_Optional_Inverse3Id], [t2].[Name] DESC");
+ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t2].[OneToMany_Optional_Inverse3Id], [t2].[Name] DESC");
}
public override async Task Filtered_include_basic_OrderBy_Take_split(bool async)
@@ -5326,7 +5326,7 @@ FROM [LevelTwo] AS [l0]
) AS [t]
WHERE [t].[row] <= 3
) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id]
-ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t0].[Id]",
+ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name]",
//
@"SELECT [t2].[Id], [t2].[Level2_Optional_Id], [t2].[Level2_Required_Id], [t2].[Name], [t2].[OneToMany_Optional_Inverse3Id], [t2].[OneToMany_Optional_Self_Inverse3Id], [t2].[OneToMany_Required_Inverse3Id], [t2].[OneToMany_Required_Self_Inverse3Id], [t2].[OneToOne_Optional_PK_Inverse3Id], [t2].[OneToOne_Optional_Self3Id], [l].[Id], [t0].[Id]
FROM [LevelOne] AS [l]
@@ -5348,7 +5348,7 @@ FROM [LevelThree] AS [l1]
) AS [t1]
WHERE 1 < [t1].[row]
) AS [t2] ON [t0].[Id] = [t2].[OneToMany_Required_Inverse3Id]
-ORDER BY [l].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t0].[Id], [t2].[OneToMany_Required_Inverse3Id], [t2].[Name] DESC");
+ORDER BY [l].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse2Id], [t0].[Name], [t2].[OneToMany_Required_Inverse3Id], [t2].[Name] DESC");
}
public override async Task Filtered_include_same_filter_set_on_same_navigation_twice_split(bool async)
@@ -5567,7 +5567,7 @@ FROM [LevelThree] AS [l1]
) AS [t]
WHERE [t].[row] <= 1
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
-ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]",
+ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]",
//
@"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id]
FROM [LevelOne] AS [l]
@@ -5582,7 +5582,7 @@ FROM [LevelThree] AS [l1]
WHERE [t].[row] <= 1
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Optional_Inverse4Id]
-ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]",
+ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]",
//
@"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id]
FROM [LevelOne] AS [l]
@@ -5597,7 +5597,7 @@ FROM [LevelThree] AS [l1]
WHERE [t].[row] <= 1
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Required_Inverse4Id]
-ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]");
+ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]");
}
public override async Task Filtered_include_complex_three_level_with_middle_having_filter2_split(bool async)
@@ -5626,7 +5626,7 @@ FROM [LevelThree] AS [l1]
) AS [t]
WHERE [t].[row] <= 1
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
-ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]",
+ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]",
//
@"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id]
FROM [LevelOne] AS [l]
@@ -5641,7 +5641,7 @@ FROM [LevelThree] AS [l1]
WHERE [t].[row] <= 1
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Optional_Inverse4Id]
-ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]",
+ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]",
//
@"SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], [l].[Id], [l0].[Id], [t0].[Id]
FROM [LevelOne] AS [l]
@@ -5656,7 +5656,7 @@ FROM [LevelThree] AS [l1]
WHERE [t].[row] <= 1
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
INNER JOIN [LevelFour] AS [l2] ON [t0].[Id] = [l2].[OneToMany_Required_Inverse4Id]
-ORDER BY [l].[Id], [l0].[Id], [t0].[OneToMany_Optional_Inverse3Id], [t0].[Id]");
+ORDER BY [l].[Id], [l0].[Id], [t0].[Id], [t0].[OneToMany_Optional_Inverse3Id]");
}
public override void Filtered_include_variable_used_inside_filter_split()
@@ -5833,6 +5833,21 @@ ELSE [l1].[Name]
END IS NULL");
}
+ public override async Task Projecting_collection_with_FirstOrDefault_without_split_works(bool async)
+ {
+ await base.Projecting_collection_with_FirstOrDefault_without_split_works(async);
+
+ AssertSql(
+ @"SELECT [t].[Id], [l0].[Id], [l0].[Date], [l0].[Level1_Optional_Id], [l0].[Level1_Required_Id], [l0].[Name], [l0].[OneToMany_Optional_Inverse2Id], [l0].[OneToMany_Optional_Self_Inverse2Id], [l0].[OneToMany_Required_Inverse2Id], [l0].[OneToMany_Required_Self_Inverse2Id], [l0].[OneToOne_Optional_PK_Inverse2Id], [l0].[OneToOne_Optional_Self2Id]
+FROM (
+ SELECT TOP(1) [l].[Id]
+ FROM [LevelOne] AS [l]
+ WHERE [l].[Id] = 1
+) AS [t]
+LEFT JOIN [LevelTwo] AS [l0] ON [t].[Id] = [l0].[OneToMany_Optional_Inverse2Id]
+ORDER BY [t].[Id], [l0].[Id]");
+ }
+
private void AssertSql(params string[] expected) => Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
}
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs
index ae66ab610e4..6f81ef47120 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyNoTrackingQuerySqlServerTest.cs
@@ -1348,7 +1348,7 @@ FROM [JoinOneToTwo] AS [j]
) AS [t]
WHERE (1 < [t].[row]) AND ([t].[row] <= 3)
) AS [t0] ON [e].[Id] = [t0].[OneId]
-ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]",
+ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]",
//
@"SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]
FROM [EntityOnes] AS [e]
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs
index 594c7a5a529..a9c8e766841 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/ManyToManyQuerySqlServerTest.cs
@@ -1348,7 +1348,7 @@ FROM [JoinOneToTwo] AS [j]
) AS [t]
WHERE (1 < [t].[row]) AND ([t].[row] <= 3)
) AS [t0] ON [e].[Id] = [t0].[OneId]
-ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]",
+ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]",
//
@"SELECT [t1].[ThreeId], [t1].[TwoId], [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]
FROM [EntityOnes] AS [e]
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs
index c980f642f3a..42b38d6c332 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyNoTrackingQuerySqlServerTest.cs
@@ -1420,7 +1420,7 @@ FROM [JoinOneToTwo] AS [j]
) AS [t]
WHERE (1 < [t].[row]) AND ([t].[row] <= 3)
) AS [t0] ON [e].[Id] = [t0].[OneId]
-ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]",
+ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]",
//
@"SELECT [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]
FROM [EntityOnes] AS [e]
diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs
index c94d56aba0a..09bd5ec8014 100644
--- a/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs
+++ b/test/EFCore.SqlServer.FunctionalTests/Query/TPTManyToManyQuerySqlServerTest.cs
@@ -1420,7 +1420,7 @@ FROM [JoinOneToTwo] AS [j]
) AS [t]
WHERE (1 < [t].[row]) AND ([t].[row] <= 3)
) AS [t0] ON [e].[Id] = [t0].[OneId]
-ORDER BY [e].[Id], [t0].[OneId], [t0].[Id], [t0].[TwoId]",
+ORDER BY [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]",
//
@"SELECT [t1].[ThreeId], [t1].[TwoId], [t1].[Id], [t1].[CollectionInverseId], [t1].[Name], [t1].[ReferenceInverseId], [e].[Id], [t0].[OneId], [t0].[TwoId], [t0].[Id]
FROM [EntityOnes] AS [e]