Skip to content

Commit f22c188

Browse files
Merge pull request #409 from Lempireqc/master
save
2 parents ccb28f9 + ac6f2f1 commit f22c188

File tree

7 files changed

+216
-22
lines changed

7 files changed

+216
-22
lines changed

Z.Dynamic.Core.Lab/Program.cs

+17-14
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,8 @@ class Program
1010
{
1111
static void Main(string[] args)
1212
{
13-
var data = new List<object> {
14-
new { ItemCode = "AAAA", Flag = true, SoNo="aaa",JobNo="JNO01" } ,
15-
new { ItemCode = "AAAA", Flag = true, SoNo="aaa",JobNo="JNO02" } ,
16-
new { ItemCode = "AAAA", Flag = false, SoNo="aaa",JobNo="JNO03" } ,
17-
new { ItemCode = "BBBB", Flag = true, SoNo="bbb",JobNo="JNO04" },
18-
new { ItemCode = "BBBB", Flag = true, SoNo="bbb",JobNo="JNO05" } ,
19-
new { ItemCode = "BBBB", Flag = true, SoNo="ccc",JobNo="JNO06" } ,
20-
};
21-
var jsonString = JsonConvert.SerializeObject(data);
22-
var list = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jsonString);
2313

24-
var groupList = list.AsQueryable().GroupBy("new (ItemCode, Flag)").ToDynamicList();
14+
Request_PropertyCaseSensitive.Execute();
2515

2616
//var data = new List<object> {
2717
// new { ItemCode = "AAAA", Flag = true, SoNo="aaa",JobNo="JNO01" } ,
@@ -32,10 +22,23 @@ static void Main(string[] args)
3222
// new { ItemCode = "BBBB", Flag = true, SoNo="ccc",JobNo="JNO06" } ,
3323
//};
3424
//var jsonString = JsonConvert.SerializeObject(data);
35-
//var list = JsonConvert.DeserializeObject<List<object>>(jsonString).ToList();
36-
//var groupList = list.Select("new (ItemCode, Flag)");
25+
//var list = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jsonString);
3726

38-
Request_Dictionary.Execute();
27+
//var groupList = list.AsQueryable().GroupBy("new (ItemCode, Flag)").ToDynamicList();
28+
29+
////var data = new List<object> {
30+
//// new { ItemCode = "AAAA", Flag = true, SoNo="aaa",JobNo="JNO01" } ,
31+
//// new { ItemCode = "AAAA", Flag = true, SoNo="aaa",JobNo="JNO02" } ,
32+
//// new { ItemCode = "AAAA", Flag = false, SoNo="aaa",JobNo="JNO03" } ,
33+
//// new { ItemCode = "BBBB", Flag = true, SoNo="bbb",JobNo="JNO04" },
34+
//// new { ItemCode = "BBBB", Flag = true, SoNo="bbb",JobNo="JNO05" } ,
35+
//// new { ItemCode = "BBBB", Flag = true, SoNo="ccc",JobNo="JNO06" } ,
36+
////};
37+
////var jsonString = JsonConvert.SerializeObject(data);
38+
////var list = JsonConvert.DeserializeObject<List<object>>(jsonString).ToList();
39+
////var groupList = list.Select("new (ItemCode, Flag)");
40+
41+
//Request_Dictionary.Execute();
3942
}
4043
}
4144
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Linq.Dynamic.Core;
5+
using System.Collections;
6+
using System.Linq.Expressions;
7+
using System.Text;
8+
9+
namespace Z.Dynamic.Core.Lab
10+
{
11+
class Request_ParameterCaseSensitive
12+
{
13+
class DataClass
14+
{
15+
public bool IsTrue;
16+
public string Name;
17+
}
18+
19+
public static void Execute()
20+
{
21+
22+
bool isTrue = true;
23+
var abc = new List<DataClass>() { new DataClass() { IsTrue = false, Name = "1" } };
24+
var x = new List<ParameterExpression>();
25+
x.Add(Expression.Parameter(isTrue.GetType(), "isTrue"));
26+
x.Add(Expression.Parameter(abc.GetType(), "abc"));
27+
28+
var config = new ParsingConfig();
29+
string query = "abc.Where(IsTrue == true)";
30+
config.IsCaseSensitive = true;
31+
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
32+
Delegate del = e.Compile();
33+
var result = ((IEnumerable)del.DynamicInvoke(isTrue, abc)).GetEnumerator();
34+
result.MoveNext();
35+
var t = result.Current;
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq.Dynamic.Core;
5+
using System.Linq.Expressions;
6+
using System.Text;
7+
8+
namespace Z.Dynamic.Core.Lab
9+
{
10+
class Request_PropertyCaseSensitive
11+
{
12+
class DataClass
13+
{
14+
public bool IsTrue;
15+
public bool ISTrue;
16+
public string Name;
17+
}
18+
19+
public static void Execute()
20+
{
21+
22+
bool isTrue = true;
23+
var abc = new List<DataClass>() { new DataClass() { IsTrue = true, Name = "1" } };
24+
var x = new List<ParameterExpression>();
25+
x.Add(Expression.Parameter(abc.GetType(), "abc"));
26+
27+
var config = new ParsingConfig();
28+
string query = "abc.Where(IsTrue == true)";
29+
config.IsCaseSensitive = true;
30+
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
31+
Delegate del = e.Compile();
32+
var result = ((IEnumerable)del.DynamicInvoke( abc)).GetEnumerator();
33+
result.MoveNext();
34+
var t = result.Current;
35+
}
36+
}
37+
}

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

+18-7
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public ExpressionParser([CanBeNull] ParameterExpression[] parameters, [NotNull]
6666
{
6767
Check.NotEmpty(expression, nameof(expression));
6868

69-
_symbols = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
69+
_symbols = new Dictionary<string, object>(parsingConfig == null ? StringComparer.OrdinalIgnoreCase : parsingConfig.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
7070
_internals = new Dictionary<string, object>();
7171

7272
if (parameters != null)
@@ -972,7 +972,7 @@ Expression ParseIdentifier()
972972

973973
if (_keywordsHelper.TryGetValue(_textParser.CurrentToken.Text, out object value) &&
974974
// Prioritize property or field over the type
975-
!(value is Type && _it != null && FindPropertyOrField(_it.Type, _textParser.CurrentToken.Text, false) != null))
975+
!(value is Type && _it != null && FindPropertyOrField(_it.Type, _textParser.CurrentToken.Text, false, _parsingConfig) != null))
976976
{
977977
Type typeValue = value as Type;
978978
if (typeValue != null)
@@ -1685,7 +1685,7 @@ Expression ParseMemberAccess(Type type, Expression instance)
16851685
return Expression.MakeIndex(instance, typeof(DynamicClass).GetProperty("Item"), new[] { Expression.Constant(id) });
16861686
}
16871687
#endif
1688-
MemberInfo member = FindPropertyOrField(type, id, instance == null);
1688+
MemberInfo member = FindPropertyOrField(type, id, instance == null,_parsingConfig);
16891689
if (member is PropertyInfo property)
16901690
{
16911691
return Expression.Property(instance, property);
@@ -2029,31 +2029,42 @@ static Exception IncompatibleOperandsError(string opName, Expression left, Expre
20292029
return ParseError(errorPos, Res.IncompatibleOperands, opName, TypeHelper.GetTypeName(left.Type), TypeHelper.GetTypeName(right.Type));
20302030
}
20312031

2032-
static MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess)
2032+
static MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess, ParsingConfig ParsingConfig)
20332033
{
20342034
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
20352035
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
20362036
foreach (Type t in TypeHelper.GetSelfAndBaseTypes(type))
20372037
{
2038-
MemberInfo[] members = t.FindMembers(MemberTypes.Property | MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName);
2038+
MemberInfo[] members = null;
2039+
2040+
if (ParsingConfig != null && ParsingConfig.IsCaseSensitive)
2041+
{
2042+
members = t.FindMembers(MemberTypes.Property | MemberTypes.Field, flags, Type.FilterName, memberName);
2043+
}
2044+
else
2045+
{
2046+
members = t.FindMembers(MemberTypes.Property | MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName);
2047+
}
2048+
20392049
if (members.Length != 0)
20402050
{
20412051
return members[0];
20422052
}
20432053
}
20442054
return null;
20452055
#else
2056+
var isCaseSensitive = (ParsingConfig != null && ParsingConfig.IsCaseSensitive);
20462057
foreach (Type t in TypeHelper.GetSelfAndBaseTypes(type))
20472058
{
20482059
// Try to find a property with the specified memberName
2049-
MemberInfo member = t.GetTypeInfo().DeclaredProperties.FirstOrDefault(x => (!staticAccess || x.GetAccessors(true)[0].IsStatic) && x.Name.ToLowerInvariant() == memberName.ToLowerInvariant());
2060+
MemberInfo member = t.GetTypeInfo().DeclaredProperties.FirstOrDefault(x => (!staticAccess || x.GetAccessors(true)[0].IsStatic) && ((isCaseSensitive && x.Name == memberName) || (!isCaseSensitive && x.Name.Equals(memberName, StringComparison.OrdinalIgnoreCase))));
20502061
if (member != null)
20512062
{
20522063
return member;
20532064
}
20542065

20552066
// If no property is found, try to get a field with the specified memberName
2056-
member = t.GetTypeInfo().DeclaredFields.FirstOrDefault(x => (!staticAccess || x.IsStatic) && x.Name.ToLowerInvariant() == memberName.ToLowerInvariant());
2067+
member = t.GetTypeInfo().DeclaredFields.FirstOrDefault(x => (!staticAccess || x.IsStatic) && ((isCaseSensitive && x.Name == memberName) || (!isCaseSensitive && x.Name.Equals(memberName, StringComparison.OrdinalIgnoreCase))));
20572068
if (member != null)
20582069
{
20592070
return member;

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

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class ParsingConfig
2222
EvaluateGroupByAtDatabase = true
2323
};
2424

25+
// NEED TEXT
26+
public bool IsCaseSensitive { get; set; }
27+
2528
/// <summary>
2629
/// Default ParsingConfig for CosmosDb
2730
/// </summary>

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public void DynamicExpressionParser_ParseLambda_UseParameterizedNamesInDynamicQu
299299
[Theory]
300300
[InlineData("NullableIntValue", "42")]
301301
[InlineData("NullableDoubleValue", "42.23")]
302-
public void DynamicExpressionParser_ParseLambda_UseParameterizedNamesInDynamicQuery_ForNullableProperty_true(string propName, string valueString)
302+
public void DynamicExpressionParser_ParseLambda_UseParameterizedNamesInDynamicQuery_ForNullableProperty_true(string propName, string valueString)
303303
{
304304
// Assign
305305
var config = new ParsingConfig

test/System.Linq.Dynamic.Core.Tests/MikArea/Comparer.cs

+102
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Globalization;
45
using System.Linq;
6+
using System.Linq.Expressions;
57
using System.Text;
68
using System.Threading.Tasks;
79
using NFluent;
@@ -23,6 +25,19 @@ public class Order
2325
{
2426
}
2527

28+
class DataClass1
29+
{
30+
public bool IsTrue;
31+
public string Name;
32+
}
33+
class DataClass2
34+
{
35+
public bool ISTrue;
36+
public bool IsTrue;
37+
public string Name;
38+
}
39+
40+
2641
[Fact]
2742
public void Comparer_OrderBy_And_ThenBy()
2843
{
@@ -75,5 +90,92 @@ public void Comparer_GroupBy()
7590
Check.That(check2.Count).IsEqualTo(check2_V2.Count());
7691
Check.That(check3.Count).IsEqualTo(check3_V2.Count());
7792
}
93+
94+
[Fact]
95+
public void Comparer_Parameter_1()
96+
{
97+
98+
bool isTrue = false;
99+
var abc = new List<DataClass1>() { new DataClass1() { IsTrue = true, Name = "1" } };
100+
var x = new List<ParameterExpression>();
101+
x.Add(Expression.Parameter(isTrue.GetType(), "isTrue"));
102+
x.Add(Expression.Parameter(abc.GetType(), "abc"));
103+
104+
var config = new ParsingConfig();
105+
string query = "abc.Where(IsTrue == true)";
106+
config.IsCaseSensitive = true;
107+
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
108+
Delegate del = e.Compile();
109+
var result = ((IEnumerable)del.DynamicInvoke(isTrue, abc)).GetEnumerator();
110+
result.MoveNext();
111+
var t = result.Current;
112+
Check.That(t).IsNotNull();
113+
}
114+
[Fact]
115+
public void Comparer_Parameter_2()
116+
{
117+
118+
bool isTrue = false;
119+
var abc = new List<DataClass1>() { new DataClass1() { IsTrue = true, Name = "1" } };
120+
var x = new List<ParameterExpression>();
121+
x.Add(Expression.Parameter(isTrue.GetType(), "isTrue"));
122+
x.Add(Expression.Parameter(abc.GetType(), "abc"));
123+
124+
var config = new ParsingConfig();
125+
string query = "abc.Where(IsTrue == true)";
126+
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
127+
Delegate del = e.Compile();
128+
var result = ((IEnumerable)del.DynamicInvoke(isTrue, abc)).GetEnumerator();
129+
result.MoveNext();
130+
var t = result.Current;
131+
Check.That(t).IsNull();
132+
}
133+
[Fact]
134+
public void Comparer_Property_1()
135+
{
136+
137+
bool isTrue = true;
138+
var abc = new List<DataClass2>() { new DataClass2() { IsTrue = true, Name = "1" } };
139+
var x = new List<ParameterExpression>();
140+
x.Add(Expression.Parameter(abc.GetType(), "abc"));
141+
142+
var config = new ParsingConfig();
143+
string query = "abc.Where(IsTrue == true)";
144+
config.IsCaseSensitive = true;
145+
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
146+
Delegate del = e.Compile();
147+
var result = ((IEnumerable)del.DynamicInvoke(abc)).GetEnumerator();
148+
result.MoveNext();
149+
var t = result.Current;
150+
Check.That(t).IsNotNull();
151+
}
152+
[Fact]
153+
public void Comparer_Property_2()
154+
{
155+
156+
bool isTrue = true;
157+
var abc = new List<DataClass2>() { new DataClass2() { IsTrue = true, Name = "1" } };
158+
var x = new List<ParameterExpression>();
159+
x.Add(Expression.Parameter(abc.GetType(), "abc"));
160+
161+
var config = new ParsingConfig();
162+
string query = "abc.Where(IsTrue == true)";
163+
object t = null;
164+
try
165+
{
166+
var e = DynamicExpressionParser.ParseLambda(config, x.ToArray(), null, query);
167+
Delegate del = e.Compile();
168+
var result = ((IEnumerable)del.DynamicInvoke(abc)).GetEnumerator();
169+
result.MoveNext();
170+
t = result.Current;
171+
172+
173+
}
174+
catch (Exception exception)
175+
{
176+
return;
177+
}
178+
Check.That(t).IsNull();
179+
}
78180
}
79181
}

0 commit comments

Comments
 (0)