Skip to content

Commit

Permalink
Query: Update table references for SelectExpression.Update method
Browse files Browse the repository at this point in the history
So that referential integrity remains consistent after we start treating SelectExpression as immutable
  • Loading branch information
smitpatel committed Mar 24, 2021
1 parent da0db88 commit c5168d4
Showing 1 changed file with 21 additions and 17 deletions.
38 changes: 21 additions & 17 deletions src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2887,6 +2887,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor)

return this;
}

var changed = false;

var newProjections = _projection;
Expand Down Expand Up @@ -3095,7 +3096,9 @@ public SelectExpression Update(
projectionMapping[kvp.Key] = kvp.Value;
}

return new SelectExpression(alias, projections.ToList(), tables.ToList(), _tableReferences.ToList(), groupBy.ToList(), orderings.ToList())
var newTableReferences = _tableReferences.ToList();
var newSelectExpression = new SelectExpression(
alias, projections.ToList(), tables.ToList(), newTableReferences, groupBy.ToList(), orderings.ToList())
{
_projectionMapping = projectionMapping,
Predicate = predicate,
Expand All @@ -3105,6 +3108,20 @@ public SelectExpression Update(
IsDistinct = distinct,
Tags = Tags
};

// We don't copy identifiers because when we are doing reconstruction pending collections are already applied.
// We don't visit pending collection with TableReferenceUpdatingExpressionVisitor for same reason.

// Remap tableReferences in new select expression
foreach (var tableReference in newTableReferences)
{
tableReference.UpdateTableReference(this, newSelectExpression);
}

var tableReferenceUpdatingExpressionVisitor = new TableReferenceUpdatingExpressionVisitor(this, newSelectExpression);
tableReferenceUpdatingExpressionVisitor.Visit(newSelectExpression);

return newSelectExpression;
}

/// <summary>
Expand Down Expand Up @@ -3136,22 +3153,9 @@ public SelectExpression Update(
Check.NotNull(groupBy, nameof(groupBy));
Check.NotNull(orderings, nameof(orderings));

var projectionMapping = new Dictionary<ProjectionMember, Expression>(_projectionMapping.Count);
foreach (var kvp in _projectionMapping)
{
projectionMapping[kvp.Key] = kvp.Value;
}

return new SelectExpression(Alias, projections.ToList(), tables.ToList(), _tableReferences.ToList(), groupBy.ToList(), orderings.ToList())
{
_projectionMapping = projectionMapping,
Predicate = predicate,
Having = having,
Offset = offset,
Limit = limit,
IsDistinct = IsDistinct,
Tags = Tags
};
#pragma warning disable CS0618 // Type or member is obsolete
return Update(projections, tables, predicate, groupBy, having, orderings, limit, offset, IsDistinct, Alias);
#pragma warning restore CS0618 // Type or member is obsolete
}

/// <inheritdoc />
Expand Down

0 comments on commit c5168d4

Please sign in to comment.