I have a nullable datetime
field and I have to convert the string
date field to a nullable datetime type (using Expression
)....I did this using the below.
Expression.Constant(Convert.ChangeType(value, Nullable.GetUnderlyingType(memberAccess.Type)));.
The memberAccess (mentioned above) is of type member expression. (From LinqExtensions.cs) Now In the code I am using Expression.Equal Method.
Expression.Equal(memberAccess, filter);
This fails here, as memberaccess type is nullable but filter.type is not nullable...
Even if I try to convert the member access type to nullable using
ConstantExpression test = Expression.Constant(Nullable.GetUnderlyingType(memberAccess.Type)),
the Type is Runtime and not DateTime.
How to use Expression.Equal
to compare nullable & non nullable field? IS there any way to convert the string type to a nullable datetime field? Either one of this will resolve my issue.
Ok..I did this way.
First Converted the type (string to datetime)
filter = Expression.Constant(
Convert.ChangeType(value, memberAccess.Type.GetGenericArguments()[0]));
then converted this expression to the desired type
Expression typeFilter = Expression.Convert(filter, memberAccess.Type);
Then used Expression.Equal(memberAccess, typeFilter)...
(memberAccess is MemberExpression
and it takes the property type from model)
If you have values Nullable values other than dates, This is how You can create an Expression tree for nullable types, suppose you have a nullable field BoardId, you can create expression tree dynamically like this
var nameValue="BoardId=111";
public static Expression<Func<T, bool>> BuildWhereExpression<T>(string nameValueQuery ) where T : class
{
Expression<Func<T, bool>> predicate = null;
PropertyInfo prop = null;
var fieldName = nameValueQuery.Split("=")[0];
var fieldValue = nameValueQuery.Split("=")[1];
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
if (property.Name.ToLower() == fieldName.ToLower())
{
prop = property;
}
}
if (prop != null)
{
var isNullable = prop.PropertyType.IsNullableType();
var parameter = Expression.Parameter(typeof(T), "x");
var member = Expression.Property(parameter, fieldName);
if (isNullable)
{
var filter1 =
Expression.Constant(
Convert.ChangeType(fieldValue, member.Type.GetGenericArguments()[0]));
Expression typeFilter = Expression.Convert(filter1, member.Type);
var body = Expression.Equal(member, typeFilter);
predicate = Expression.Lambda<Func<T, bool>>(body, parameter);
}
else
{
if (prop.PropertyType == typeof(string) && likeOerator.ToLower() == "like")
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, prop);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(fieldValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
predicate = Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
else
{
var constant = Expression.Constant(Convert.ChangeType(fieldValue, prop.PropertyType));
var body = Expression.Equal(member, constant);
predicate = Expression.Lambda<Func<T, bool>>(body, parameter); `enter code here`
}
}
}
return predicate;
}
1- This Solution first checks for the Nullable value and generate the expression. This is How you can determine if the type is Nullable. I have created an extension method for that purpose
public static bool IsNullableType(this Type type)
{
return type.IsGenericType && (type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
}
2- the second step is to check the type if its string then create an expression for a string.
3- the Third step is to check is value is not nullable not string then create an expression using equal
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With