Skip to content

Commit 251d90e

Browse files
authored
Fix DynamicExpressionParser and ExpressionPromoter to support LambdExpression (#649)
* Fix DynamicExpressionParser and ExpressionPromoter to support LambdaExpression * ut
1 parent 7ac62da commit 251d90e

File tree

3 files changed

+42
-24
lines changed

3 files changed

+42
-24
lines changed

src/System.Linq.Dynamic.Core/DynamicExpressionParser.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -120,24 +120,24 @@ public static LambdaExpression ParseLambda(Type? delegateType, ParsingConfig? pa
120120

121121
var parsedExpression = parser.Parse(resultType, createParameterCtor);
122122

123-
LambdaExpression lambdaExpression;
123+
if (parsedExpression is LambdaExpression lambdaExpression)
124+
{
125+
return lambdaExpression;
126+
}
127+
124128
if (parsingConfig is { RenameParameterExpression: true } && parameters.Length == 1)
125129
{
126130
var renamer = new ParameterExpressionRenamer(parser.LastLambdaItName);
127-
parsedExpression = renamer.Rename(parsedExpression, out ParameterExpression newParameterExpression);
131+
parsedExpression = renamer.Rename(parsedExpression, out var newParameterExpression);
128132

129-
lambdaExpression = delegateType == null ?
133+
return delegateType == null ?
130134
Expression.Lambda(parsedExpression, newParameterExpression) :
131135
Expression.Lambda(delegateType, parsedExpression, newParameterExpression);
132136
}
133-
else
134-
{
135-
lambdaExpression = delegateType == null ?
136-
Expression.Lambda(parsedExpression, parameters) :
137-
Expression.Lambda(delegateType, parsedExpression, parameters);
138-
}
139137

140-
return lambdaExpression;
138+
return delegateType == null ?
139+
Expression.Lambda(parsedExpression, parameters) :
140+
Expression.Lambda(delegateType, parsedExpression, parameters);
141141
}
142142

143143
/// <summary>

src/System.Linq.Dynamic.Core/Parser/ExpressionPromoter.cs

+12-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@ public ExpressionPromoter(ParsingConfig config)
2222
/// <inheritdoc />
2323
public virtual Expression? Promote(Expression expr, Type type, bool exact, bool convertExpr)
2424
{
25-
if (expr.Type == type || type.IsGenericParameter)
25+
Type returnType;
26+
if (expr is LambdaExpression lambdaExpression)
27+
{
28+
returnType = lambdaExpression.GetReturnType();
29+
}
30+
else
31+
{
32+
returnType = expr.Type;
33+
}
34+
35+
if (returnType == type || type.IsGenericParameter)
2636
{
2737
return expr;
2838
}
@@ -103,7 +113,7 @@ public ExpressionPromoter(ParsingConfig config)
103113
}
104114
}
105115

106-
if (TypeHelper.IsCompatibleWith(expr.Type, type))
116+
if (TypeHelper.IsCompatibleWith(returnType, type))
107117
{
108118
if (type == typeof(decimal) && TypeHelper.IsEnumType(expr.Type))
109119
{

test/System.Linq.Dynamic.Core.Tests/DynamicExpressionParserTests.cs

+20-12
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ public void DynamicExpressionParser_ParseLambda_Select_2()
580580

581581
// https://github.com/StefH/System.Linq.Dynamic.Core/issues/58
582582
[Fact]
583-
public void DynamicExpressionParser_ParseLambda_4_Issue58()
583+
public void DynamicExpressionParser_ParseLambda_Issue58()
584584
{
585585
var expressionParams = new[]
586586
{
@@ -1251,14 +1251,16 @@ public void DynamicExpressionParser_ParseLambda_Operator_Less_Greater_With_Guids
12511251
}
12521252

12531253
[Theory]
1254-
[InlineData("c => c.Age == 8", "c => (c.Age == 8)")]
1255-
[InlineData("c => c.Name == \"test\"", "c => (c.Name == \"test\")")]
1256-
public void DynamicExpressionParser_ParseLambda_RenameParameterExpression(string expressionAsString, string expected)
1254+
[InlineData(true, "c => c.Age == 8", "c => (c.Age == 8)")]
1255+
[InlineData(true, "c => c.Name == \"test\"", "c => (c.Name == \"test\")")]
1256+
[InlineData(false, "c => c.Age == 8", "Param_0 => (Param_0.Age == 8)")]
1257+
[InlineData(false, "c => c.Name == \"test\"", "Param_0 => (Param_0.Name == \"test\")")]
1258+
public void DynamicExpressionParser_ParseLambda_RenameParameterExpression(bool renameParameterExpression, string expressionAsString, string expected)
12571259
{
12581260
// Arrange
12591261
var config = new ParsingConfig
12601262
{
1261-
RenameParameterExpression = true
1263+
RenameParameterExpression = renameParameterExpression
12621264
};
12631265

12641266
// Act
@@ -1500,22 +1502,28 @@ public void DynamicExpressionParser_ParseLambda_Func()
15001502
}
15011503

15021504
[Theory]
1503-
[InlineData(1, true)]
1504-
[InlineData(5, false)]
1505-
public void DynamicExpressionParser_ParseLambda_Func2(int? input, bool expected)
1505+
[InlineData("value", "value != null && value == 1", 1, true)]
1506+
[InlineData("value", "value != null && value == 1", 5, false)]
1507+
[InlineData("x", "value != null && value == 1", 1, true)]
1508+
[InlineData("x", "value != null && value == 1", 5, false)]
1509+
[InlineData(null, "value != null && value == 1", 1, true)]
1510+
[InlineData(null, "value != null && value == 1", 5, false)]
1511+
[InlineData("value", "value => value != null && value == 1", 1, true)]
1512+
[InlineData("value", "value => value != null && value == 1", 5, false)]
1513+
public void DynamicExpressionParser_ParseLambda_Func2(string? paramName, string test, int? input, bool expected)
15061514
{
15071515
// Arrange
15081516
var nullableType = typeof(int?);
1509-
var functionType = typeof(Func<,>).MakeGenericType(nullableType, typeof(bool));
1510-
var valueParameter = Expression.Parameter(nullableType, "value");
1517+
var delegateType = typeof(Func<,>).MakeGenericType(nullableType, typeof(bool));
1518+
var valueParameter = paramName is not null ? Expression.Parameter(nullableType, paramName) : Expression.Parameter(nullableType);
15111519

15121520
// Act 1
15131521
var expression = DynamicExpressionParser.ParseLambda(
1514-
functionType,
1522+
delegateType,
15151523
new ParsingConfig(),
15161524
new[] { valueParameter },
15171525
typeof(bool),
1518-
"value != null && value == 1"
1526+
test
15191527
);
15201528

15211529
// Act 2

0 commit comments

Comments
 (0)