【问题标题】:Linq Expression For DateTime Equality Nullable Issue日期时间相等可空问题的 Linq 表达式
【发布时间】:2017-03-01 14:30:37
【问题描述】:

我正在尝试使用以下代码 sn-p 从 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 多个搜索字段,每个字段都有一个选择下拉菜单,提供比较运算符,例如:等于、小于、大于等。

所以我正在编写一些表达式来处理特定的数据类型。这将使用通用模式及时转换为库。

使用以下代码定义 [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));

但这只是抛出同样的错误,然后我将常量替换为空值给我:

var ComparisonExpression = Expression.Equal(Expression.Call(
                           Expression.Invoke(searchColumnName, row),
                           typeof(DateTime).GetMethod("CompareTo", new[] { typeof(DateTime) }),
                           Expression.Constant(toDate, typeof(DateTime))),
                           null);

虽然这不起作用,但提供的错误表明它不喜欢空值参数。

我遇到了以下链接How to compare only date part with linq expression?

我已经尝试过这里的建议,它表明需要一个 between 操作。也没有工作。

【问题讨论】:

  • 这个sn-p中有很多错误,修复一个只会让你进入下一个。原来的异常表明Expression.Invoke(searchColumnName, row)的类型是DateTime?。你最好告诉我们你想要达到什么目标并展示整个方法。

标签: c# entity-framework linq


【解决方案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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多