Skip to content

Commit f60437e

Browse files
committed
Merged pr/38 into pull-requests-branch
2 parents dae09f2 + 4010cf2 commit f60437e

3 files changed

Lines changed: 81 additions & 12 deletions

File tree

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Generic;
2+
using System.ComponentModel;
23
using System.Linq.Expressions;
34
using System.Reflection;
45
using System.Collections;
@@ -633,6 +634,10 @@ Expression ParseComparison()
633634
_token.id == TokenId.GreaterThan || _token.id == TokenId.GreaterThanEqual ||
634635
_token.id == TokenId.LessThan || _token.id == TokenId.LessThanEqual)
635636
{
637+
ConstantExpression constantExpr;
638+
#if !SILVERLIGHT
639+
TypeConverter typeConverter;
640+
#endif
636641
Token op = _token;
637642
NextToken();
638643
Expression right = ParseShift();
@@ -659,8 +664,6 @@ Expression ParseComparison()
659664
{
660665
if (left.Type != right.Type)
661666
{
662-
ConstantExpression constantExpr;
663-
664667
Expression e;
665668
if ((e = PromoteExpression(right, left.Type, true)) != null)
666669
{
@@ -702,6 +705,16 @@ Expression ParseComparison()
702705
}
703706
}
704707
}
708+
#if !SILVERLIGHT
709+
else if ((constantExpr = right as ConstantExpression) != null && constantExpr.Value is string && (typeConverter = TypeDescriptor.GetConverter(left.Type)) != null)
710+
{
711+
right = Expression.Constant(typeConverter.ConvertFromInvariantString((string)constantExpr.Value), left.Type);
712+
}
713+
else if ((constantExpr = left as ConstantExpression) != null && constantExpr.Value is string && (typeConverter = TypeDescriptor.GetConverter(right.Type)) != null)
714+
{
715+
left = Expression.Constant(typeConverter.ConvertFromInvariantString((string)constantExpr.Value), right.Type);
716+
}
717+
#endif
705718
else
706719
{
707720
CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
@@ -1288,7 +1301,7 @@ static Expression GenerateConversion(Expression expr, Type type, int errorPos)
12881301
return Expression.Constant(dateTime, type);
12891302

12901303
object[] arguments = { text, null };
1291-
#if NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD
1304+
#if NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD
12921305
MethodInfo method = type.GetMethod("TryParse", new[] { typeof(string), type.MakeByRefType() });
12931306
#else
12941307
MethodInfo method = type.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), type.MakeByRefType() }, null);
@@ -1582,7 +1595,7 @@ static bool IsUnsignedIntegralType(Type type)
15821595
static int GetNumericTypeKind(Type type)
15831596
{
15841597
type = GetNonNullableType(type);
1585-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1598+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
15861599
if (type.GetTypeInfo().IsEnum) return 0;
15871600

15881601
switch (Type.GetTypeCode(type))
@@ -1650,7 +1663,7 @@ static Exception IncompatibleOperandsError(string opName, Expression left, Expre
16501663

16511664
static MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess)
16521665
{
1653-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1666+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
16541667
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly | (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
16551668
foreach (Type t in SelfAndBaseTypes(type))
16561669
{
@@ -1680,7 +1693,7 @@ static MemberInfo FindPropertyOrField(Type type, string memberName, bool staticA
16801693

16811694
int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method)
16821695
{
1683-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1696+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
16841697
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
16851698
(staticAccess ? BindingFlags.Static : BindingFlags.Instance);
16861699
foreach (Type t in SelfAndBaseTypes(type))
@@ -1709,7 +1722,7 @@ int FindIndexer(Type type, Expression[] args, out MethodBase method)
17091722
{
17101723
foreach (Type t in SelfAndBaseTypes(type))
17111724
{
1712-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1725+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
17131726
MemberInfo[] members = t.GetDefaultMembers();
17141727
#else
17151728
MemberInfo[] members = new MemberInfo[0];
@@ -1718,7 +1731,7 @@ int FindIndexer(Type type, Expression[] args, out MethodBase method)
17181731
{
17191732
IEnumerable<MethodBase> methods = members
17201733
.OfType<PropertyInfo>().
1721-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1734+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
17221735
Select(p => (MethodBase)p.GetGetMethod()).
17231736
Where(m => m != null);
17241737
#else
@@ -1831,7 +1844,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact)
18311844
{
18321845
Type target = GetNonNullableType(type);
18331846
object value = null;
1834-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1847+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
18351848
switch (Type.GetTypeCode(ce.Type))
18361849
{
18371850
case TypeCode.Int32:
@@ -1880,7 +1893,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact)
18801893

18811894
static object ParseNumber(string text, Type type)
18821895
{
1883-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
1896+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
18841897
switch (Type.GetTypeCode(GetNonNullableType(type)))
18851898
{
18861899
case TypeCode.SByte:
@@ -1991,7 +2004,7 @@ static object ParseNumber(string text, Type type)
19912004

19922005
static object ParseEnum(string name, Type type)
19932006
{
1994-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
2007+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
19952008
if (type.IsEnum)
19962009
{
19972010
MemberInfo[] memberInfos = type.FindMembers(MemberTypes.Field,
@@ -2010,7 +2023,7 @@ static object ParseEnum(string name, Type type)
20102023

20112024
static bool IsCompatibleWith(Type source, Type target)
20122025
{
2013-
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
2026+
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
20142027
if (source == target) return true;
20152028
if (!target.IsValueType) return target.IsAssignableFrom(source);
20162029
Type st = GetNonNullableType(source);

src/System.Linq.Dynamic.Core/project.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,32 +42,51 @@
4242
},
4343
"net45": {
4444
"frameworkAssemblies": {
45+
},
46+
"dependencies": {
47+
"System.ComponentModel.TypeConverter": "4.1.0"
4548
}
4649
},
4750
"net451": {
4851
"frameworkAssemblies": {
52+
},
53+
"dependencies": {
54+
"System.ComponentModel.TypeConverter": "4.1.0"
4955
}
5056
},
5157
"net452": {
5258
"frameworkAssemblies": {
59+
},
60+
"dependencies": {
61+
"System.ComponentModel.TypeConverter": "4.1.0"
5362
}
5463
},
5564
"net46": {
5665
"frameworkAssemblies": {
66+
},
67+
"dependencies": {
68+
"System.ComponentModel.TypeConverter": "4.1.0"
5769
}
5870
},
5971
"net461": {
6072
"frameworkAssemblies": {
73+
},
74+
"dependencies": {
75+
"System.ComponentModel.TypeConverter": "4.1.0"
6176
}
6277
},
6378
"dnx451": {
6479
"frameworkAssemblies": {
80+
},
81+
"dependencies": {
82+
"System.ComponentModel.TypeConverter": "4.1.0"
6583
}
6684
},
6785
"netcore45": {
6886
"buildOptions": { "define": [ "WINDOWS_APP" ] },
6987
"dependencies": {
7088
"System.Collections.Concurrent": "4.0.10",
89+
"System.ComponentModel.TypeConverter": "4.1.0",
7190
"System.Dynamic.Runtime": "4.0.0",
7291
"System.Linq": "4.0.0",
7392
"System.Linq.Expressions": "4.0.0",
@@ -82,6 +101,7 @@
82101
"buildOptions": { "define": [ "WINDOWS_APP" ] },
83102
"dependencies": {
84103
"System.Collections.Concurrent": "4.0.10",
104+
"System.ComponentModel.TypeConverter": "4.1.0",
85105
"System.Dynamic.Runtime": "4.0.0",
86106
"System.Linq": "4.0.0",
87107
"System.Linq.Expressions": "4.0.0",
@@ -96,6 +116,7 @@
96116
"buildOptions": { "define": [ "WINDOWS_APP" ] },
97117
"dependencies": {
98118
"System.Collections.Concurrent": "4.0.12",
119+
"System.ComponentModel.TypeConverter": "4.1.0",
99120
"System.Diagnostics.Debug": "4.0.11",
100121
"System.Dynamic.Runtime": "4.0.11",
101122
"System.Globalization": "4.0.11",
@@ -114,6 +135,7 @@
114135
],
115136
"dependencies": {
116137
"System.Collections.Concurrent": "4.0.12",
138+
"System.ComponentModel.TypeConverter": "4.1.0",
117139
"System.Diagnostics.Debug": "4.0.11",
118140
"System.Dynamic.Runtime": "4.0.11",
119141
"System.Globalization": "4.0.11",
@@ -142,6 +164,7 @@
142164
"dependencies": {
143165
"System.Collections": "4.0.11",
144166
"System.Collections.Concurrent": "4.0.12",
167+
"System.ComponentModel.TypeConverter": "4.1.0",
145168
"System.Diagnostics.Debug": "4.0.11",
146169
"System.Dynamic.Runtime": "4.0.11",
147170
"System.Linq.Expressions": "4.1.0",

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,39 @@ public void ExpressionTests_Enum()
485485
Assert.Equal(TestEnum.Var5, result7.Single());
486486
}
487487

488+
[Fact]
489+
public void ExpressionTests_DateTimeString()
490+
{
491+
GlobalConfig.CustomTypeProvider = new NetStandardCustomTypeProvider();
492+
493+
//Arrange
494+
var lst = new List<DateTime> { DateTime.Today, DateTime.Today.AddDays(1), DateTime.Today.AddDays(2) };
495+
var qry = lst.AsQueryable();
496+
497+
//Act
498+
var result1 = qry.Where("it = @0", lst[0].ToString());
499+
500+
//Assert
501+
Assert.Equal(lst[0], result1.Single());
502+
}
503+
504+
[Fact]
505+
public void ExpressionTests_GuidString()
506+
{
507+
GlobalConfig.CustomTypeProvider = new NetStandardCustomTypeProvider();
508+
509+
//Arrange
510+
var lst = new List<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
511+
var qry = lst.AsQueryable();
512+
513+
//Act
514+
var result1 = qry.Where("it = @0", lst[0].ToString());
515+
516+
//Assert
517+
Assert.Equal(lst[0], result1.Single());
518+
}
519+
520+
488521
[Fact]
489522
public void ExpressionTests_CompareWithGuid()
490523
{

0 commit comments

Comments
 (0)