|
9 | 9 | namespace Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; |
10 | 10 |
|
11 | 11 | /// <summary> |
12 | | -/// Converts <see cref="SqlServerOpenJsonExpression" /> expressions with WITH (the default) to OPENJSON without WITH when an |
13 | | -/// ordering still exists on the [key] column, i.e. when the ordering of the original JSON array needs to be preserved |
14 | | -/// (e.g. limit/offset). |
| 12 | +/// Converts <see cref="SqlServerOpenJsonExpression" /> expressions with WITH (the default) to OPENJSON without WITH under the following |
| 13 | +/// conditions: |
| 14 | +/// * When an ordering still exists on the [key] column, i.e. when the ordering of the original JSON array needs to be preserved |
| 15 | +/// (e.g. limit/offset). |
| 16 | +/// * When the column type in the WITH clause is a SQL Server "CLR type" - these are incompatible with WITH (e.g. hierarchy id). |
15 | 17 | /// </summary> |
16 | 18 | /// <remarks> |
17 | 19 | /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to |
@@ -79,14 +81,17 @@ public virtual Expression Process(Expression expression) |
79 | 81 | { |
80 | 82 | var table = selectExpression.Tables[i]; |
81 | 83 |
|
82 | | - if ((table is SqlServerOpenJsonExpression { ColumnInfos: not null } |
83 | | - or JoinExpressionBase { Table: SqlServerOpenJsonExpression { ColumnInfos: not null } }) |
84 | | - && selectExpression.Orderings.Select(o => o.Expression) |
85 | | - .Concat(selectExpression.Projection.Select(p => p.Expression)) |
86 | | - .Any(x => IsKeyColumn(x, table))) |
| 84 | + if (table.UnwrapJoin() is SqlServerOpenJsonExpression { ColumnInfos: not null } openJsonExpression |
| 85 | + && ( |
| 86 | + // Condition 1: an ordering still refers to the OPENJSON's [key] column - ordering needs to be preserved. |
| 87 | + selectExpression.Orderings.Select(o => o.Expression) |
| 88 | + .Concat(selectExpression.Projection.Select(p => p.Expression)) |
| 89 | + .Any(x => IsKeyColumn(x, table)) |
| 90 | + || |
| 91 | + // Condition 2: a column type in the WITH clause is a SQL Server "CLR type" (e.g. hierarchy id). |
| 92 | + openJsonExpression.ColumnInfos.Any(c => c.TypeMapping.StoreType is "hierarchyid"))) |
87 | 93 | { |
88 | 94 | // Remove the WITH clause from the OPENJSON expression |
89 | | - var openJsonExpression = (SqlServerOpenJsonExpression)((table as JoinExpressionBase)?.Table ?? table); |
90 | 95 | var newOpenJsonExpression = openJsonExpression.Update( |
91 | 96 | openJsonExpression.JsonExpression, |
92 | 97 | openJsonExpression.Path, |
|
0 commit comments