Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions src/System.Linq.Dynamic.Core/ExpressionParser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
using System.Collections;
Expand Down Expand Up @@ -633,6 +634,10 @@ Expression ParseComparison()
_token.id == TokenId.GreaterThan || _token.id == TokenId.GreaterThanEqual ||
_token.id == TokenId.LessThan || _token.id == TokenId.LessThanEqual)
{
ConstantExpression constantExpr;
#if !SILVERLIGHT
TypeConverter typeConverter;
#endif
Token op = _token;
NextToken();
Expression right = ParseShift();
Expand All @@ -659,8 +664,6 @@ Expression ParseComparison()
{
if (left.Type != right.Type)
{
ConstantExpression constantExpr;

Expression e;
if ((e = PromoteExpression(right, left.Type, true)) != null)
{
Expand Down Expand Up @@ -702,6 +705,16 @@ Expression ParseComparison()
}
}
}
#if !SILVERLIGHT
else if ((constantExpr = right as ConstantExpression) != null && constantExpr.Value is string && (typeConverter = TypeDescriptor.GetConverter(left.Type)) != null)
{
right = Expression.Constant(typeConverter.ConvertFromInvariantString((string)constantExpr.Value), left.Type);
}
else if ((constantExpr = left as ConstantExpression) != null && constantExpr.Value is string && (typeConverter = TypeDescriptor.GetConverter(right.Type)) != null)
{
left = Expression.Constant(typeConverter.ConvertFromInvariantString((string)constantExpr.Value), right.Type);
}
#endif
else
{
CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
Expand Down Expand Up @@ -1288,7 +1301,7 @@ static Expression GenerateConversion(Expression expr, Type type, int errorPos)
return Expression.Constant(dateTime, type);

object[] arguments = { text, null };
#if NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD
#if NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD
MethodInfo method = type.GetMethod("TryParse", new[] { typeof(string), type.MakeByRefType() });
#else
MethodInfo method = type.GetMethod("TryParse", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(string), type.MakeByRefType() }, null);
Expand Down Expand Up @@ -1582,7 +1595,7 @@ static bool IsUnsignedIntegralType(Type type)
static int GetNumericTypeKind(Type type)
{
type = GetNonNullableType(type);
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
if (type.GetTypeInfo().IsEnum) return 0;

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

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

int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method)
{
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
(staticAccess ? BindingFlags.Static : BindingFlags.Instance);
foreach (Type t in SelfAndBaseTypes(type))
Expand Down Expand Up @@ -1709,7 +1722,7 @@ int FindIndexer(Type type, Expression[] args, out MethodBase method)
{
foreach (Type t in SelfAndBaseTypes(type))
{
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
MemberInfo[] members = t.GetDefaultMembers();
#else
MemberInfo[] members = new MemberInfo[0];
Expand All @@ -1718,7 +1731,7 @@ int FindIndexer(Type type, Expression[] args, out MethodBase method)
{
IEnumerable<MethodBase> methods = members
.OfType<PropertyInfo>().
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
Select(p => (MethodBase)p.GetGetMethod()).
Where(m => m != null);
#else
Expand Down Expand Up @@ -1831,7 +1844,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact)
{
Type target = GetNonNullableType(type);
object value = null;
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
switch (Type.GetTypeCode(ce.Type))
{
case TypeCode.Int32:
Expand Down Expand Up @@ -1880,7 +1893,7 @@ Expression PromoteExpression(Expression expr, Type type, bool exact)

static object ParseNumber(string text, Type type)
{
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
switch (Type.GetTypeCode(GetNonNullableType(type)))
{
case TypeCode.SByte:
Expand Down Expand Up @@ -1991,7 +2004,7 @@ static object ParseNumber(string text, Type type)

static object ParseEnum(string name, Type type)
{
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
if (type.IsEnum)
{
MemberInfo[] memberInfos = type.FindMembers(MemberTypes.Field,
Expand All @@ -2010,7 +2023,7 @@ static object ParseEnum(string name, Type type)

static bool IsCompatibleWith(Type source, Type target)
{
#if !(NETFX_CORE ||WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
#if !(NETFX_CORE || WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
if (source == target) return true;
if (!target.IsValueType) return target.IsAssignableFrom(source);
Type st = GetNonNullableType(source);
Expand Down
23 changes: 23 additions & 0 deletions src/System.Linq.Dynamic.Core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,51 @@
},
"net45": {
"frameworkAssemblies": {
},
"dependencies": {
"System.ComponentModel.TypeConverter": "4.1.0"
}
},
"net451": {
"frameworkAssemblies": {
},
"dependencies": {
"System.ComponentModel.TypeConverter": "4.1.0"
}
},
"net452": {
"frameworkAssemblies": {
},
"dependencies": {
"System.ComponentModel.TypeConverter": "4.1.0"
}
},
"net46": {
"frameworkAssemblies": {
},
"dependencies": {
"System.ComponentModel.TypeConverter": "4.1.0"
}
},
"net461": {
"frameworkAssemblies": {
},
"dependencies": {
"System.ComponentModel.TypeConverter": "4.1.0"
}
},
"dnx451": {
"frameworkAssemblies": {
},
"dependencies": {
"System.ComponentModel.TypeConverter": "4.1.0"
}
},
"netcore45": {
"buildOptions": { "define": [ "WINDOWS_APP" ] },
"dependencies": {
"System.Collections.Concurrent": "4.0.10",
"System.ComponentModel.TypeConverter": "4.1.0",
"System.Dynamic.Runtime": "4.0.0",
"System.Linq": "4.0.0",
"System.Linq.Expressions": "4.0.0",
Expand All @@ -82,6 +101,7 @@
"buildOptions": { "define": [ "WINDOWS_APP" ] },
"dependencies": {
"System.Collections.Concurrent": "4.0.10",
"System.ComponentModel.TypeConverter": "4.1.0",
"System.Dynamic.Runtime": "4.0.0",
"System.Linq": "4.0.0",
"System.Linq.Expressions": "4.0.0",
Expand All @@ -96,6 +116,7 @@
"buildOptions": { "define": [ "WINDOWS_APP" ] },
"dependencies": {
"System.Collections.Concurrent": "4.0.12",
"System.ComponentModel.TypeConverter": "4.1.0",
"System.Diagnostics.Debug": "4.0.11",
"System.Dynamic.Runtime": "4.0.11",
"System.Globalization": "4.0.11",
Expand All @@ -114,6 +135,7 @@
],
"dependencies": {
"System.Collections.Concurrent": "4.0.12",
"System.ComponentModel.TypeConverter": "4.1.0",
"System.Diagnostics.Debug": "4.0.11",
"System.Dynamic.Runtime": "4.0.11",
"System.Globalization": "4.0.11",
Expand Down Expand Up @@ -142,6 +164,7 @@
"dependencies": {
"System.Collections": "4.0.11",
"System.Collections.Concurrent": "4.0.12",
"System.ComponentModel.TypeConverter": "4.1.0",
"System.Diagnostics.Debug": "4.0.11",
"System.Dynamic.Runtime": "4.0.11",
"System.Linq.Expressions": "4.1.0",
Expand Down
33 changes: 33 additions & 0 deletions test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,39 @@ public void ExpressionTests_Enum()
Assert.Equal(TestEnum.Var5, result6.Single());
}

[Fact]
public void ExpressionTests_DateTimeString()
{
GlobalConfig.CustomTypeProvider = new NetStandardCustomTypeProvider();

//Arrange
var lst = new List<DateTime> { DateTime.Today, DateTime.Today.AddDays(1), DateTime.Today.AddDays(2) };
var qry = lst.AsQueryable();

//Act
var result1 = qry.Where("it = @0", lst[0].ToString());

//Assert
Assert.Equal(lst[0], result1.Single());
}

[Fact]
public void ExpressionTests_GuidString()
{
GlobalConfig.CustomTypeProvider = new NetStandardCustomTypeProvider();

//Arrange
var lst = new List<Guid> { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };
var qry = lst.AsQueryable();

//Act
var result1 = qry.Where("it = @0", lst[0].ToString());

//Assert
Assert.Equal(lst[0], result1.Single());
}


[Fact]
public void ExpressionTests_CompareWithGuid()
{
Expand Down