我正在尝试使用以下代码片段从SQL Server搜索DateTime数据字段:
DateTime toDate = DateTime.Parse("14-11-2016");
如您所见,toDate字段不为空。
var maxComparisonExpression = Expression.Equal(Expression.Call(
Expression.Invoke(searchColumnName, row),
typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) }),
Expression.Constant(toDate, typeof(DateTime))),
Expression.Constant(0, typeof(DateTime)));
当此代码粗鲁时,执行maxComparisonExpression时会显示以下错误。
Method 'Int32 CompareTo(System.DateTime)' declared on type 'System.DateTime' cannot be called with instance of type 'System.Nullable`1[System.DateTime]'
到目前为止,我已将typeof(DateTime)更改为typeof(DateTime?),这没有效果。
我认为它与第二个参数
有关Expression.Constant(0, typeof(DateTime))
但我看不出如何解决这个问题。任何人都可以向我展示一些解决这个问题的方法吗?
更新:
我有一个用于高级搜索的页面。在这个页面上有超过20个搜索字段,每个搜索字段都有一个选择下拉列表,提供比较运算符,如:equals,less than,greater then等。
所以我正在编写一些表达式来处理特定的数据类型。这个时间将使用通用模式转换为库。
使用以下代码定义[field] == fromInt在Linqpad中执行正常
int fromInt = 101462975;
Expression<Func<Table_Name, int>> searchColumnName = x => x.Id;
IQueryable<Table_Name> retval = Entities.Table_Name.AsQueryable();
var row = Expression.Parameter(typeof(Table_Name), "Table_Name");
var ComparisonExpression = Expression.Equal(Expression.Call(
Expression.Invoke(searchColumnName, row),
typeof(int).GetMethod("CompareTo", new[] { typeof(int) }),
Expression.Constant(fromInt)),
Expression.Constant(0, typeof(int)));
因此,假设将int的数据类型更改为DateTime的假设是前进的方法。
LinqPad的完整代码是:
DateTime? toDate = DateTime.Parse("14-11-2016");
Expression<Func<Table_Name, DateTime?>> searchColumnName = x => x.Created_date;
IQueryable<Table_Name> retval = Entities.Table_Name.AsQueryable();
var row = Expression.Parameter(typeof(Table_Name), "Table_Name");
var ComparisonExpression = Expression.Equal(Expression.Call(
Expression.Invoke(searchColumnName, row),
typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) }),
Expression.Constant(toDate, typeof(DateTime))),
Expression.Constant(0, typeof(DateTime)));
我尝试将上面的行更改为
Expression.Constant(0));
但是这只会抛出同样的错误,然后我将常量替换为null值给我:
var ComparisonExpression = Expression.Equal(Expression.Call(
Expression.Invoke(searchColumnName, row),
typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) }),
Expression.Constant(toDate, typeof(DateTime))),
null);
虽然这不起作用,但提供的错误表明它不喜欢null值参数。
我遇到了以下链接How to compare only date part with linq expression?
我已经尝试了这里建议的内容,它表明需要在操作之间进行操作。也没用。
答案 0 :(得分:1)
CompareTo
的结果是整数,但您希望将结果与DateTime
进行比较:
Expression.Constant(0, typeof(DateTime /* oops */))
这没有意义,是吗?与int
:
Expression.Constant(0, typeof(int))
在这种情况下,您可以简单地省略类型:
Expression.Constant(0)
另一个问题是Expression.Invoke(searchColumnName, row)
会返回DateTime?
,而不是DateTime
。你必须以这种或那种方式进行转换。您可以添加GetDateTimeValue
方法:
var ComparisonExpression = Expression.Equal(Expression.Call(
GetDateTimeValue(Expression.Invoke(searchColumnName, row)),
typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) }),
Expression.Constant(toDate, typeof(DateTime))),
null);
GetDateTimeValue
的位置:
private readonly static MethodInfo nullableDateTimeGetValueOrDefaultMethodInfo = typeof(DateTime?).GetMethod(nameof(Nullable<DateTime>.GetValueOrDefault), new Type[] { });
private static Expression GetDateTimeValue(Expression expr)
{
return Expression.Call(expr, nullableDateTimeGetValueOrDefaultMethodInfo);
}