我试图弄清楚如何使用ExpressionType创建谓词。等于将Nullable Datetime与静态日期或用户输入进行比较。
下面我将举一个简单的例子
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);
问题
我已经尝试了一些解决方案,但是我总是遇到与字符串转换相关的异常,不知道为什么。
生成的表达式
{item =>(item.Test == Convert(1/1/1900 12:00:00 AM,Nullable`1))}
“从字符串转换日期和/或时间时转换失败。”
对此有何想法?
更新
我将EF Core和datetime用于SQL日期列
我刚刚注意到,如果我手动进行过滤,则会产生相同的错误
allExamples = allExamples.Where(x => x.Test == new Datetime(1900, 1, 1));
但是如果您声明该变量,它将很好地工作
var date = new Datetime(1900, 1, 1);
allExamples = allExamples.Where(x => x.Test == date);
如何动态创建表达式以像上一个示例一样工作?
谢谢