Skip to content

Commit c4b97ac

Browse files
authored
UseParameterizedNamesInDynamicQuery=false (#214)
* UseParameterizedNamesInDynamicQuery=false * Adedd more tests for ConstantExpressionWrapper * Fix tests
1 parent 8fbec9b commit c4b97ac

File tree

4 files changed

+189
-62
lines changed

4 files changed

+189
-62
lines changed

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

+12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ public void Wrap(ref Expression expression)
1818
{
1919
expression = WrappedConstant((bool)constantExpression.Value);
2020
}
21+
if (constantExpression.Type == typeof(char))
22+
{
23+
expression = WrappedConstant((char)constantExpression.Value);
24+
}
25+
if (constantExpression.Type == typeof(byte))
26+
{
27+
expression = WrappedConstant((byte)constantExpression.Value);
28+
}
29+
if (constantExpression.Type == typeof(sbyte))
30+
{
31+
expression = WrappedConstant((sbyte)constantExpression.Value);
32+
}
2133
else if (constantExpression.Type == typeof(string))
2234
{
2335
expression = WrappedConstant((string)constantExpression.Value);

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public IExpressionPromoter ExpressionPromoter
8989
/// Use Parameterized Names in generated dynamic SQL query. Default set to true.
9090
/// See https://github.com/graeme-hill/gblog/blob/master/source_content/articles/2014.139_entity-framework-dynamic-queries-and-parameterization.mkd
9191
/// </summary>
92-
public bool UseParameterizedNamesInDynamicQuery { get; set; } = true;
92+
public bool UseParameterizedNamesInDynamicQuery { get; set; } = false;
9393

9494
/// <summary>
9595
/// Allows the New() keyword to evaluate any available Type.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System.Linq.Dynamic.Core.Parser;
2+
using System.Linq.Expressions;
3+
using NFluent;
4+
using Xunit;
5+
6+
namespace System.Linq.Dynamic.Core.Tests
7+
{
8+
public class ConstantExpressionWrapperTests
9+
{
10+
private readonly IConstantExpressionWrapper _constantExpressionWrapper;
11+
12+
public ConstantExpressionWrapperTests()
13+
{
14+
_constantExpressionWrapper = new ConstantExpressionWrapper();
15+
}
16+
17+
[Theory]
18+
[InlineData(true)]
19+
[InlineData((int)1)]
20+
[InlineData((uint)2)]
21+
[InlineData((short)3)]
22+
[InlineData((ushort)4)]
23+
[InlineData(5L)]
24+
[InlineData(6UL)]
25+
[InlineData(7.1f)]
26+
[InlineData(8.1d)]
27+
[InlineData('c')]
28+
[InlineData((byte) 10)]
29+
[InlineData((sbyte) 11)]
30+
public void ConstantExpressionWrapper_Wrap_ConstantExpression_PrimitiveTypes<T>(T test)
31+
{
32+
// Assign
33+
var expression = Expression.Constant(test) as Expression;
34+
35+
// Act
36+
_constantExpressionWrapper.Wrap(ref expression);
37+
38+
// Verify
39+
Check.That(expression).IsNotNull();
40+
41+
var constantExpression = (expression as MemberExpression).Expression as ConstantExpression;
42+
dynamic wrappedObj = constantExpression.Value;
43+
44+
T value = wrappedObj.Value;
45+
46+
Check.That(value).IsEqualTo(test);
47+
}
48+
49+
[Fact]
50+
public void ConstantExpressionWrapper_Wrap_ConstantExpression_String()
51+
{
52+
// Assign
53+
string test = "abc";
54+
var expression = Expression.Constant(test) as Expression;
55+
56+
// Act
57+
_constantExpressionWrapper.Wrap(ref expression);
58+
59+
// Verify
60+
Check.That(expression).IsNotNull();
61+
62+
var constantExpression = (expression as MemberExpression).Expression as ConstantExpression;
63+
dynamic wrappedObj = constantExpression.Value;
64+
65+
string value = wrappedObj.Value;
66+
67+
Check.That(value).IsEqualTo(test);
68+
}
69+
70+
[Fact]
71+
public void ConstantExpressionWrapper_Wrap_ConstantExpression_ComplexTypes()
72+
{
73+
// Assign
74+
var test = DateTime.Now;
75+
var expression = Expression.Constant(test) as Expression;
76+
77+
// Act
78+
_constantExpressionWrapper.Wrap(ref expression);
79+
80+
// Verify
81+
Check.That(expression).IsNotNull();
82+
83+
var constantExpression = (expression as MemberExpression).Expression as ConstantExpression;
84+
dynamic wrappedObj = constantExpression.Value;
85+
86+
DateTime value = wrappedObj.Value;
87+
88+
Check.That(value).IsEqualTo(test);
89+
}
90+
}
91+
}

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

+85-61
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ public virtual HashSet<Type> GetCustomTypes()
9999
return _customTypes;
100100
}
101101

102-
_customTypes = new HashSet<Type>(FindTypesMarkedWithDynamicLinqTypeAttribute(new[] { GetType().GetTypeInfo().Assembly }));
102+
_customTypes =
103+
new HashSet<Type>(
104+
FindTypesMarkedWithDynamicLinqTypeAttribute(new[] { GetType().GetTypeInfo().Assembly }));
103105
_customTypes.Add(typeof(CustomClassWithStaticMethod));
104106
_customTypes.Add(typeof(StaticHelper));
105107
return _customTypes;
@@ -111,6 +113,45 @@ public Type ResolveType(string typeName)
111113
}
112114
}
113115

116+
[Fact]
117+
public void ParseLambda_UseParameterizedNamesInDynamicQuery_true()
118+
{
119+
// Assign
120+
var config = new ParsingConfig
121+
{
122+
UseParameterizedNamesInDynamicQuery = true
123+
};
124+
125+
// Act
126+
var expression = DynamicExpressionParser.ParseLambda<string, bool>(config, true, "s => s == \"x\"");
127+
128+
// Assert
129+
dynamic constantExpression = ((MemberExpression)(expression.Body as BinaryExpression).Right).Expression as ConstantExpression;
130+
dynamic wrappedObj = constantExpression.Value;
131+
string value = wrappedObj.Value;
132+
133+
Check.That(value).IsEqualTo("x");
134+
}
135+
136+
[Fact]
137+
public void ParseLambda_UseParameterizedNamesInDynamicQuery_false()
138+
{
139+
// Assign
140+
var config = new ParsingConfig
141+
{
142+
UseParameterizedNamesInDynamicQuery = false
143+
};
144+
145+
// Act
146+
var expression = DynamicExpressionParser.ParseLambda<string, bool>(config, true, "s => s == \"x\"");
147+
148+
// Assert
149+
dynamic constantExpression = (ConstantExpression)(expression.Body as BinaryExpression).Right;
150+
string value = constantExpression.Value;
151+
152+
Check.That(value).IsEqualTo("x");
153+
}
154+
114155
[Fact]
115156
public void ParseLambda_ToList()
116157
{
@@ -141,16 +182,20 @@ public void ParseLambda_Complex_1()
141182

142183
var externals = new Dictionary<string, object>
143184
{
144-
{ "Users", qry }
185+
{"Users", qry}
145186
};
146187

147188
// Act
148-
string query = "Users.GroupBy(x => new { x.Profile.Age }).OrderBy(gg => gg.Key.Age).Select(j => new (j.Key.Age, j.Sum(k => k.Income) As TotalIncome))";
189+
string query =
190+
"Users.GroupBy(x => new { x.Profile.Age }).OrderBy(gg => gg.Key.Age).Select(j => new (j.Key.Age, j.Sum(k => k.Income) As TotalIncome))";
149191
LambdaExpression expression = DynamicExpressionParser.ParseLambda(null, query, externals);
150192
Delegate del = expression.Compile();
151193
IEnumerable<dynamic> result = del.DynamicInvoke() as IEnumerable<dynamic>;
152194

153-
var expected = qry.GroupBy(x => new { x.Profile.Age }).OrderBy(gg => gg.Key.Age).Select(j => new { j.Key.Age, TotalIncome = j.Sum(k => k.Income) }).Select(c => new ComplexParseLambda1Result { Age = c.Age, TotalIncome = c.TotalIncome }).Cast<dynamic>().ToArray();
195+
var expected = qry.GroupBy(x => new { x.Profile.Age }).OrderBy(gg => gg.Key.Age)
196+
.Select(j => new { j.Key.Age, TotalIncome = j.Sum(k => k.Income) })
197+
.Select(c => new ComplexParseLambda1Result { Age = c.Age, TotalIncome = c.TotalIncome }).Cast<dynamic>()
198+
.ToArray();
154199

155200
// Assert
156201
Check.That(result).IsNotNull();
@@ -166,12 +211,16 @@ public void ParseLambda_Complex_2()
166211
var qry = testList.AsQueryable();
167212

168213
// Act
169-
string query = "GroupBy(x => new { x.Profile.Age }, it).OrderBy(gg => gg.Key.Age).Select(j => new (j.Key.Age, j.Sum(k => k.Income) As TotalIncome))";
214+
string query =
215+
"GroupBy(x => new { x.Profile.Age }, it).OrderBy(gg => gg.Key.Age).Select(j => new (j.Key.Age, j.Sum(k => k.Income) As TotalIncome))";
170216
LambdaExpression expression = DynamicExpressionParser.ParseLambda(qry.GetType(), null, query);
171217
Delegate del = expression.Compile();
172218
IEnumerable<dynamic> result = del.DynamicInvoke(qry) as IEnumerable<dynamic>;
173219

174-
var expected = qry.GroupBy(x => new { x.Profile.Age }, x => x).OrderBy(gg => gg.Key.Age).Select(j => new { j.Key.Age, TotalIncome = j.Sum(k => k.Income) }).Select(c => new ComplexParseLambda1Result { Age = c.Age, TotalIncome = c.TotalIncome }).Cast<dynamic>().ToArray();
220+
var expected = qry.GroupBy(x => new { x.Profile.Age }, x => x).OrderBy(gg => gg.Key.Age)
221+
.Select(j => new { j.Key.Age, TotalIncome = j.Sum(k => k.Income) })
222+
.Select(c => new ComplexParseLambda1Result { Age = c.Age, TotalIncome = c.TotalIncome }).Cast<dynamic>()
223+
.ToArray();
175224

176225
// Assert
177226
Check.That(result).IsNotNull();
@@ -197,8 +246,10 @@ public void ParseLambda_Complex_3()
197246
};
198247

199248
// Act
200-
string stringExpression = "Users.GroupBy(x => new { x.Profile.Age }).OrderBy(gg => gg.Key.Age).Select(j => new System.Linq.Dynamic.Core.Tests.DynamicExpressionParserTests+ComplexParseLambda3Result{j.Key.Age, j.Sum(k => k.Income) As TotalIncome})";
201-
LambdaExpression expression = DynamicExpressionParser.ParseLambda(config, null, stringExpression, externals);
249+
string stringExpression =
250+
"Users.GroupBy(x => new { x.Profile.Age }).OrderBy(gg => gg.Key.Age).Select(j => new System.Linq.Dynamic.Core.Tests.DynamicExpressionParserTests+ComplexParseLambda3Result{j.Key.Age, j.Sum(k => k.Income) As TotalIncome})";
251+
LambdaExpression expression =
252+
DynamicExpressionParser.ParseLambda(config, null, stringExpression, externals);
202253
Delegate del = expression.Compile();
203254
IEnumerable<dynamic> result = del.DynamicInvoke() as IEnumerable<dynamic>;
204255

@@ -262,13 +313,14 @@ public void ParseLambda_4_Issue58()
262313
{
263314
var expressionParams = new[]
264315
{
265-
Expression.Parameter(typeof (MyClass), "myObj")
316+
Expression.Parameter(typeof(MyClass), "myObj")
266317
};
267318

268319
var myClassInstance = new MyClass();
269320
var invokersMerge = new List<object> { myClassInstance };
270321

271-
LambdaExpression expression = DynamicExpressionParser.ParseLambda(false, expressionParams, null, "myObj.Foo()");
322+
LambdaExpression expression =
323+
DynamicExpressionParser.ParseLambda(false, expressionParams, null, "myObj.Foo()");
272324
Delegate del = expression.Compile();
273325
object result = del.DynamicInvoke(invokersMerge.ToArray());
274326

@@ -385,22 +437,25 @@ public void ParseLambda_RealNumbers()
385437
[Fact]
386438
public void ParseLambda_StringLiteral_ReturnsBooleanLambdaExpression()
387439
{
388-
var expression = DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(typeof(string), "Property1") }, typeof(bool), "Property1 == \"test\"");
440+
var expression = DynamicExpressionParser.ParseLambda(
441+
new[] { Expression.Parameter(typeof(string), "Property1") }, typeof(bool), "Property1 == \"test\"");
389442
Assert.Equal(typeof(bool), expression.Body.Type);
390443
}
391444

392445
[Fact]
393446
public void ParseLambda_StringLiteralEmpty_ReturnsBooleanLambdaExpression()
394447
{
395-
var expression = DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(typeof(string), "Property1") }, typeof(bool), "Property1 == \"\"");
448+
var expression = DynamicExpressionParser.ParseLambda(
449+
new[] { Expression.Parameter(typeof(string), "Property1") }, typeof(bool), "Property1 == \"\"");
396450
Assert.Equal(typeof(bool), expression.Body.Type);
397451
}
398452

399453
[Fact]
400454
public void ParseLambda_Config_StringLiteralEmpty_ReturnsBooleanLambdaExpression()
401455
{
402456
var config = new ParsingConfig();
403-
var expression = DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(typeof(string), "Property1") }, typeof(bool), "Property1 == \"\"");
457+
var expression = DynamicExpressionParser.ParseLambda(
458+
new[] { Expression.Parameter(typeof(string), "Property1") }, typeof(bool), "Property1 == \"\"");
404459
Assert.Equal(typeof(bool), expression.Body.Type);
405460
}
406461

@@ -415,20 +470,9 @@ public void ParseLambda_StringLiteralEmbeddedQuote_ReturnsBooleanLambdaExpressio
415470
typeof(bool),
416471
string.Format("Property1 == {0}", expectedRightValue));
417472

418-
var notWrappedExpression = DynamicExpressionParser.ParseLambda(
419-
new[] { Expression.Parameter(typeof(string), "Property1") },
420-
typeof(bool),
421-
string.Format("Property1 == {0} + \"\"", expectedRightValue));
422-
423-
var notWrappedExpectedRightValue = ((ConstantExpression)((MethodCallExpression)((BinaryExpression)notWrappedExpression.Body).Right).Arguments[0]).Value;
424-
425-
var constantExpression = (ConstantExpression)((MemberExpression)((BinaryExpression)expression.Body).Right).Expression;
426-
dynamic wrappedObj = constantExpression.Value;
427-
428-
// Assert
429-
string rightValue = wrappedObj.Value;
473+
string rightValue = ((BinaryExpression)expression.Body).Right.ToString();
430474
Assert.Equal(typeof(bool), expression.Body.Type);
431-
Assert.Equal(notWrappedExpectedRightValue, rightValue);
475+
Assert.Equal(expectedRightValue, rightValue);
432476
}
433477

434478
[Fact]
@@ -442,19 +486,9 @@ public void ParseLambda_StringLiteralStartEmbeddedQuote_ReturnsBooleanLambdaExpr
442486
typeof(bool),
443487
string.Format("Property1 == {0}", expectedRightValue));
444488

445-
var notWrappedExpression = DynamicExpressionParser.ParseLambda(
446-
new[] { Expression.Parameter(typeof(string), "Property1") },
447-
typeof(bool),
448-
string.Format("Property1 == {0} + \"\"", expectedRightValue));
449-
450-
var notWrappedExpectedRightValue = ((ConstantExpression)((MethodCallExpression)((BinaryExpression)notWrappedExpression.Body).Right).Arguments[0]).Value;
451-
452-
var constantExpression = (ConstantExpression)((MemberExpression)((BinaryExpression)expression.Body).Right).Expression;
453-
dynamic wrappedObj = constantExpression.Value;
454-
455-
string rightValue = wrappedObj.Value;
489+
string rightValue = ((BinaryExpression)expression.Body).Right.ToString();
456490
Assert.Equal(typeof(bool), expression.Body.Type);
457-
Assert.Equal(notWrappedExpectedRightValue, rightValue);
491+
Assert.Equal(expectedRightValue, rightValue);
458492
}
459493

460494
[Fact]
@@ -480,20 +514,9 @@ public void ParseLambda_StringLiteralEscapedBackslash_ReturnsBooleanLambdaExpres
480514
typeof(bool),
481515
string.Format("Property1 == {0}", expectedRightValue));
482516

483-
var notWrappedExpression = DynamicExpressionParser.ParseLambda(
484-
new[] { Expression.Parameter(typeof(string), "Property1") },
485-
typeof(bool),
486-
string.Format("Property1 == {0} + \"\"", expectedRightValue));
487-
488-
var notWrappedExpectedRightValue = ((ConstantExpression)((MethodCallExpression)((BinaryExpression)notWrappedExpression.Body).Right).Arguments[0]).Value;
489-
490-
var constantExpression = (ConstantExpression)((MemberExpression)((BinaryExpression)expression.Body).Right).Expression;
491-
dynamic wrappedObj = constantExpression.Value;
492-
493-
// Assert
494-
string rightValue = wrappedObj.Value;
495-
Assert.Equal(typeof(bool), expression.Body.Type);
496-
Assert.Equal(notWrappedExpectedRightValue, rightValue);
517+
string rightValue = ((BinaryExpression)expression.Body).Right.ToString();
518+
Assert.Equal(typeof(Boolean), expression.Body.Type);
519+
Assert.Equal(expectedRightValue, rightValue);
497520
}
498521

499522
[Fact]
@@ -509,11 +532,8 @@ public void ParseLambda_TupleToStringMethodCall_ReturnsStringLambdaExpression()
509532
[Fact]
510533
public void ParseLambda_IllegalMethodCall_ThrowsException()
511534
{
512-
Check.ThatCode(() =>
513-
{
514-
DynamicExpressionParser.ParseLambda(typeof(IO.FileStream), null, "it.Close()");
515-
})
516-
.Throws<ParseException>().WithMessage("Methods on type 'Stream' are not accessible");
535+
Check.ThatCode(() => { DynamicExpressionParser.ParseLambda(typeof(IO.FileStream), null, "it.Close()"); })
536+
.Throws<ParseException>().WithMessage("Methods on type 'Stream' are not accessible");
517537
}
518538

519539
[Fact]
@@ -526,10 +546,12 @@ public void ParseLambda_CustomMethod()
526546
};
527547

528548
var context = new CustomClassWithStaticMethod();
529-
string expression = $"{nameof(CustomClassWithStaticMethod)}.{nameof(CustomClassWithStaticMethod.GetAge)}(10)";
549+
string expression =
550+
$"{nameof(CustomClassWithStaticMethod)}.{nameof(CustomClassWithStaticMethod.GetAge)}(10)";
530551

531552
// Act
532-
var lambdaExpression = DynamicExpressionParser.ParseLambda(config, typeof(CustomClassWithStaticMethod), null, expression);
553+
var lambdaExpression =
554+
DynamicExpressionParser.ParseLambda(config, typeof(CustomClassWithStaticMethod), null, expression);
533555
Delegate del = lambdaExpression.Compile();
534556
int result = (int)del.DynamicInvoke(context);
535557

@@ -600,7 +622,8 @@ public void ParseLambda_With_Guid_Equals_String()
600622
var user = new User();
601623
user.Id = someId;
602624
Guid guidEmpty = Guid.Empty;
603-
string expressionText = $"iif(@0.Id == \"{someId}\", Guid.Parse(\"{guidEmpty}\"), Guid.Parse(\"{anotherId}\"))";
625+
string expressionText =
626+
$"iif(@0.Id == \"{someId}\", Guid.Parse(\"{guidEmpty}\"), Guid.Parse(\"{anotherId}\"))";
604627

605628
// Act
606629
var lambda = DynamicExpressionParser.ParseLambda(typeof(User), null, expressionText, user);
@@ -676,7 +699,8 @@ public void ParseLambda_Operator_Less_Greater_With_Guids()
676699
var user = new User();
677700
user.Id = someId;
678701
Guid guidEmpty = Guid.Empty;
679-
string expressionText = $"iif(@0.Id == StaticHelper.GetGuid(\"name\"), Guid.Parse(\"{guidEmpty}\"), Guid.Parse(\"{anotherId}\"))";
702+
string expressionText =
703+
$"iif(@0.Id == StaticHelper.GetGuid(\"name\"), Guid.Parse(\"{guidEmpty}\"), Guid.Parse(\"{anotherId}\"))";
680704

681705
// Act
682706
var lambda = DynamicExpressionParser.ParseLambda(config, typeof(User), null, expressionText, user);

0 commit comments

Comments
 (0)