Skip to content

Commit 4ce1803

Browse files
mayorovphazzik
authored andcommitted
Resolved Compute - Include - Decompile problem
1 parent f128ea6 commit 4ce1803

File tree

1 file changed

+45
-1
lines changed

1 file changed

+45
-1
lines changed

src/DelegateDecompiler/DecompileExpressionVisitor.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using System.Linq;
33
using System.Linq.Expressions;
44
using System.Reflection;
@@ -12,6 +12,50 @@ public static Expression Decompile(Expression expression)
1212
return new DecompileExpressionVisitor().Visit(expression);
1313
}
1414

15+
private static readonly object NULL = new object(); // for use as a dictionary key
16+
private readonly Dictionary<object, Expression> visitedConstants;
17+
18+
private bool hasAnyChanges = false;
19+
public override Expression Visit(Expression node)
20+
{
21+
var result = base.Visit(node);
22+
if (result != node)
23+
hasAnyChanges = true;
24+
return result;
25+
}
26+
27+
private DecompileExpressionVisitor(Dictionary<object, Expression> sharedVisitedConstants = null)
28+
{
29+
this.visitedConstants = sharedVisitedConstants ?? new Dictionary<object, Expression>();
30+
}
31+
32+
protected override Expression VisitConstant(ConstantExpression node)
33+
{
34+
Expression result;
35+
if (visitedConstants.TryGetValue(node.Value ?? NULL, out result))
36+
{
37+
return result; // avoid infinite recursion
38+
}
39+
40+
if (typeof(IQueryable).IsAssignableFrom(node.Type))
41+
{
42+
visitedConstants.Add(node.Value ?? NULL, node);
43+
44+
var value = (IQueryable)node.Value;
45+
var childVisitor = new DecompileExpressionVisitor(visitedConstants);
46+
result = childVisitor.Visit(value.Expression);
47+
48+
if (childVisitor.hasAnyChanges)
49+
{
50+
result = Expression.Constant(value.Provider.CreateQuery(result), node.Type);
51+
visitedConstants[node.Value ?? NULL] = result;
52+
return result;
53+
}
54+
}
55+
56+
return node;
57+
}
58+
1559
protected override Expression VisitMember(MemberExpression node)
1660
{
1761
if (ShouldDecompile(node.Member) && node.Member is PropertyInfo property)

0 commit comments

Comments
 (0)