2017-03-01 41 views
1

我試圖使用下面的代碼段的SQL服務器搜索DateTime數據字段:LINQ表達式爲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)) 

,但我看不出如何解決此問題。任何人都可以向我展示一些解決此問題的方法嗎?

更新:

我有一個用於高級搜索的頁面。在此頁面上有二十多個搜索字段,每個具有選擇下拉菜單中提供比較運營商如:等於,小於,大於等

所以我寫了一些表達式來處理特定的數據類型。這在時間上將使用通用模式轉換爲庫。

使用下面的代碼來定義[現場] == 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); 

雖然這不起作用,但提供的錯誤表明它是二d不喜歡空值參數。

我所遇到下面的鏈接How to compare only date part with linq expression?

我已經試過什麼建議在這裏由此表明,一個操作之間是必需的。也沒有工作。

+0

有在這個片段中許多錯誤,解決了一個只想讓你到下一個。原始異常表明'Expression.Invoke(searchColumnName,row)'的類型是'DateTime?'。你最好告訴我們你想做什麼,並展示整個方法。 –

回答

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); 
}