I am trying to figure it out how to create a predicate using ExpressionType.Equal to compare a Nullable Datetime with a static date or with a user input.
Below I am gonna give a simple example
public class Example
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime? Test { get; set; }
}
public class PredicateBuilder
{
public static Expression<Func<T, bool>> Create<T>(string memberPath,
string operatorName,
object targetValue)
{
var param = Expression.Parameter(typeof(T), "item");
var left = memberPath
.Split(CommonConstants.Separator)
.Aggregate((Expression)param, Expression.PropertyOrField);
var underlyingType = Nullable.GetUnderlyingType(left.Type);
var memberType = underlyingType ?? left.Type;
Expression exp;
if (Enum.TryParse(operatorName, out ExpressionType tBinary))
{
var right = Expression.Constant(Convert.ChangeType(targetValue, memberType));
var typeFilter = Expression.Convert(right, left.Type);
exp = Expression.MakeBinary(tBinary, left, typeFilter);
}
else
{
exp = Expression.Call(
left,
operatorName, // method
Type.EmptyTypes, // no generic type arguments
Expression.Constant(Convert.ChangeType(targetValue, memberType)) // argument
);
}
return Expression.Lambda<Func<T, bool>>(exp, param);
}
}
// In my concrete implementantion came up the need of comparing a certain date with 1900/1/1
IQueryable<Example> allExamples = ...;
var filterExpression = filterExp = PredicateBuilder.Create<Example>("Test",
nameof(ExpressionType.Equal),
new DateTime(1900, 1, 1));
allExamples = allExamples.Where(filterExpression);
Problem
I've tried a few solutions but I am always getting an exception related with a string conversion don't know why.
Generated Expression
{item => (item.Test == Convert(1/1/1900 12:00:00 AM, Nullable`1))}
"Conversion failed when converting date and/or time from character string."
Any thoughts on this?
Update
I am using EF Core and datetime for the SQL date columns
I just noticed that if I do the filter manually will produce the same error
allExamples = allExamples.Where(x => x.Test == new Datetime(1900, 1, 1));
but if you declare the variable it works fine
var date = new Datetime(1900, 1, 1);
allExamples = allExamples.Where(x => x.Test == date);
How to create an expression dynamically to work like this last example?
Thanks
Aucun commentaire:
Enregistrer un commentaire