Skip to content

Commit

Permalink
Query: Skip updating NewExpression without ctor
Browse files Browse the repository at this point in the history
Scenario: NewExpression of struct type which does not have any ctor arguments (so new DateTime()). New DateTime(2019, 12, 11) still has ctor so it works fine. Struct type could be user defined or system defined.
Root cause: When calling NewExpression.Update the way checking if arguments are changed is different in .NET Framework & Core. Since arguments are 0, it should not need to be updated. .NET Core identifies this correctly and does not cause regeneration avoiding the exception.
  • Loading branch information
smitpatel committed Oct 17, 2019
1 parent edf5b27 commit 6774c70
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,12 @@ protected override Expression VisitTypeBinary(TypeBinaryExpression typeBinaryExp

protected override Expression VisitNew(NewExpression newExpression)
{
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

var newArguments = new List<Expression>();
foreach (var argument in newExpression.Arguments)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ protected override Expression VisitExtension(Expression extensionExpression)

protected override Expression VisitNew(NewExpression newExpression)
{
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

if (newExpression.Arguments.Count == 0)
{
return newExpression;
Expand Down
6 changes: 6 additions & 0 deletions src/EFCore.InMemory/Query/Internal/InMemoryQueryExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,12 @@ private Expression GetGroupingKey(Expression key, List<Expression> groupingExpre
switch (key)
{
case NewExpression newExpression:
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

var arguments = new Expression[newExpression.Arguments.Count];
for (var i = 0; i < arguments.Length; i++)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ private Expression TranslateGroupingKey(Expression expression)
switch (expression)
{
case NewExpression newExpression:
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

if (newExpression.Arguments.Count == 0)
{
return newExpression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ protected override Expression VisitExtension(Expression extensionExpression)

protected override Expression VisitNew(NewExpression newExpression)
{
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

if (newExpression.Arguments.Count == 0)
{
return newExpression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ private Expression TranslateGroupingKey(Expression expression)
switch (expression)
{
case NewExpression newExpression:
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

if (newExpression.Arguments.Count == 0)
{
return newExpression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ protected override Expression VisitConstant(ConstantExpression constantExpressio

protected override Expression VisitNew(NewExpression newExpression)
{
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

var visitedArgs = Visit(newExpression.Arguments);
var visitedExpression = newExpression.Update(visitedArgs.Select(Unwrap));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp

protected override Expression VisitNew(NewExpression newExpression)
{
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return newExpression;
}

var arguments = new Expression[newExpression.Arguments.Count];
for (var i = 0; i < newExpression.Arguments.Count; i++)
{
Expand All @@ -382,6 +388,13 @@ private bool ReconstructAnonymousType(Expression currentRoot, NewExpression newE
{
replacement = null;
var changed = false;

// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return false;
}

if (newExpression.Arguments.Count > 0
&& newExpression.Members == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,12 @@ private Expression SnapshotExpression(Expression selector)

case NewExpression newExpression:
{
// For .NET Framework only. If ctor is null that means the type is struct and has no ctor args.
if (newExpression.Constructor == null)
{
return Expression.Default(newExpression.Type);
}

var arguments = new Expression[newExpression.Arguments.Count];
for (var i = 0; i < newExpression.Arguments.Count; i++)
{
Expand Down

0 comments on commit 6774c70

Please sign in to comment.