Skip to content
This repository has been archived by the owner on Dec 2, 2020. It is now read-only.

Commit

Permalink
Fix comparison between T and Nullable<T>
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladislav Zhukov committed Jun 19, 2018
1 parent bad9260 commit 05d8931
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
6 changes: 1 addition & 5 deletions src/QueryDesignerCore/Expressions/OrderExpression.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
//------------------------------------------------------------------
// <author>Жуков Владислав</author>
//------------------------------------------------------------------

using System;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
Expand Down
50 changes: 38 additions & 12 deletions src/QueryDesignerCore/Expressions/WhereExpression.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
//------------------------------------------------------------------
// <author>Жуков Владислав</author>
//------------------------------------------------------------------

using System;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
Expand Down Expand Up @@ -86,6 +82,12 @@ internal static class WhereExpression
typeof(TimeSpan?),
typeof(bool),
typeof(bool?),
typeof(byte?),
typeof(sbyte?),
typeof(short),
typeof(short?),
typeof(ushort),
typeof(ushort?),
typeof(int),
typeof(int?),
typeof(uint),
Expand Down Expand Up @@ -222,32 +224,32 @@ private static Expression GenerateExpressionOneField(Expression prop, WhereFilte
case WhereFilterType.Equal:
return Expression.Equal(
prop,
Expression.Constant(TryCastFieldValueType(filter.Value, prop.Type)));
ToConstantExpressionOfType(TryCastFieldValueType(filter.Value, prop.Type), prop.Type));

case WhereFilterType.NotEqual:
return Expression.NotEqual(
prop,
Expression.Constant(TryCastFieldValueType(filter.Value, prop.Type)));
ToConstantExpressionOfType(TryCastFieldValueType(filter.Value, prop.Type), prop.Type));

case WhereFilterType.LessThan:
return Expression.LessThan(
prop,
Expression.Constant(TryCastFieldValueType(filter.Value, prop.Type)));
ToConstantExpressionOfType(TryCastFieldValueType(filter.Value, prop.Type), prop.Type));

case WhereFilterType.GreaterThan:
return Expression.GreaterThan(
prop,
Expression.Constant(TryCastFieldValueType(filter.Value, prop.Type)));
ToConstantExpressionOfType(TryCastFieldValueType(filter.Value, prop.Type), prop.Type));

case WhereFilterType.LessThanOrEqual:
return Expression.LessThanOrEqual(
prop,
Expression.Constant(TryCastFieldValueType(filter.Value, prop.Type)));
ToConstantExpressionOfType(TryCastFieldValueType(filter.Value, prop.Type), prop.Type));

case WhereFilterType.GreaterThanOrEqual:
return Expression.GreaterThanOrEqual(
prop,
Expression.Constant(TryCastFieldValueType(filter.Value, prop.Type)));
ToConstantExpressionOfType(TryCastFieldValueType(filter.Value, prop.Type), prop.Type));

case WhereFilterType.StartsWith:
return Expression.Call(prop, StartsMethod, Expression.Constant(filter.Value, StringType));
Expand Down Expand Up @@ -303,7 +305,18 @@ private static object TryCastFieldValueType(object value, Type type)


var s = Convert.ToString(value);
var res = Activator.CreateInstance(type);
object res;

if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = type.GenericTypeArguments[0];
res = Activator.CreateInstance(typeof(Nullable<>).MakeGenericType(type));
}
else
{
res = Activator.CreateInstance(type);
}

var argTypes = new[] { StringType, type.MakeByRefType() };
object[] args = { s, res };
var tryParse = type.GetRuntimeMethod("TryParse", argTypes);
Expand All @@ -314,6 +327,19 @@ private static object TryCastFieldValueType(object value, Type type)
return args[1];
}

/// <summary>
/// Converter to an nullable expression type.
/// </summary>
/// <returns>The constant expression of type.</returns>
/// <param name="obj">Filter value.</param>
/// <param name="type">Conversion to type.</param>
private static Expression ToConstantExpressionOfType(object obj, Type type) {
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
return Expression.Convert(Expression.Constant(obj), type);

return Expression.Constant(obj);
}


/// <summary>
/// Cast IEnumerable to IQueryable.
Expand Down

0 comments on commit 05d8931

Please sign in to comment.