2012-01-05 70 views
5

我想重用我一直使用的相同的代碼,但現在它遇到了一個錯誤。可空對象必須有一個值#2

我循環通過各種用戶表,並在那裏我這樣做:

DateTime dcdt = (DateTime)u.DateCreated; 
DateTime lldt = (DateTime)u.LastLogon; 
userRow["DateCreated"] = dcdt.ToShortDateString(); 

內循環。我得到的錯誤:不是 「DCDT」,這是第一位的

System.InvalidOperationException: Nullable object must have a value. 

錯誤亮點 「LLDT」 行。這本身就很奇怪。檢查數據庫中的這些字段「允許空值」。而且他們都可能是空的或者都不是空的。

這兩個值都列爲DateTime?通過智能感知類型。

我不明白爲什麼ASP.NET拒絕讓我在空日期輸出空白。如果它爲空/空,那麼邏輯會建議ASP.NET應該只是不打印任何東西。

我還想如何輸出空日期?我試圖添加if語句來防止嘗試投射null DateTimes,但它沒有幫助,這是沒有意義的。

回答

12

正如你所說的u.LastLogon數據類型是DateTime?。這意味着它可能有或沒有價值。通過鑄造到DateTime,您需要它具有價值。在這種情況下,它不會。

取決於你想用它做什麼,你可能要檢查的HasValue屬性:

userRow["LastLogon"] = u.LastLogin.HasValue ? 
         (object) u.LastLogin.ToShortDateString() : DBNull.Value; 

如果你的數據庫LastLogon列是DateTime類型的,那麼你應該能夠要做到:

userRow["LastLogon"] = u.LastLogin.HasValue ? 
         (object) u.LastLogin.Value : DBNull.Value; 
+0

那我該怎麼辦呢?我不投?我是否繼續在DateTime上使用ShortDateString()?而不是DateTime? – Dexter 2012-01-05 20:24:10

+0

如果列類型是DateTime,請參閱我的更新 – 2012-01-05 20:27:34

+1

「u.LastLogon.Value.ToShortDateString()」究竟是如何工作的? – 2012-01-05 20:47:06

1

問題是.NET null與SQL NULL不一樣。 SQL空值是System.DBNull。所以它是.NET中的[非null]值。

+0

那麼我該如何使它不打印或打印日期(如果可用)? – Dexter 2012-01-05 20:26:08

+0

技術上Frazell是正確的,但我很確定翻譯是自動發生的。如果您的日期時間列爲空,您將看到.net空。但這不是問題,你必須編寫一些代碼來檢查它是否爲空並且什麼也不打印。正如你所看到的,最緊湊的方式是使用?。 ASP.NET不會爲你做這件事。 – 2012-01-05 20:50:25

1

貌似你試圖調用一個日期時間的方法(dcdt.ToShortDateString())?這沒有一個值(它確實是空)。試試這個:

dcdt.HasValue ? dcdt.ToShortDateString() : String.Empty; 

編輯(只是重新閱讀的問題):另外,不要嘗試轉換爲DateTime。保留可空。

編輯#2(基於評論):

試試這個:

if (dcdt.HasValue) 
{ userRow["DateCreated"] = dcdt.ToShortDateString(); } 
else 
{ userRow = DbNull.Value } 
+0

u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString():DBNull.Value;或u.LastLogon.HasValue? u.LastLogon.ToShortDateString():DBNull.Value;拒絕工作。它不會像那樣編譯。 LastLogon是一種DateTime ?. – Dexter 2012-01-05 20:32:18

+0

那是因爲DBNull.Value不是一個字符串 - 表達式必須返回一致的數據類型。我會適當編輯 – 2012-01-05 20:34:21

+0

我想我解決了它。我用這個:userRow [「LastLogon」] = u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString():String.Empty; – Dexter 2012-01-05 20:38:46

1

你需要做這樣的事情在你的數據訪問代碼如下:

DataTable dt  = ExecuteSomeQuery() ; 
object  value = dt.Rows[0]["nullable_datetime_column"] ; 
DateTime? instance = value != null && value is DateTime ? (DateTime?)value : (DateTime?)null) ; 

如果返回柱是NULL,它將被返回爲System.DBNull,否則將返回爲日期時間的一個實例(或任何適當的映射類型爲— INT,字符串等)。因此,您需要在嘗試轉換之前檢查查詢返回的對象的類型。

+0

它已經是DateTime了?類型。現在我想在DateTime類中使用ShortDateTimeString函數將其轉換爲String。它不會讓我。 – Dexter 2012-01-05 20:34:35

+1

在這種情況下,'string s = instance.HasValue? instance.Value.ToString():「」;'應該做的伎倆。 – 2012-01-05 20:37:51

+0

是的,這是正確的。但其他人有點擊敗你正確格式的答案。 – Dexter 2012-01-05 20:49:16

1

我看到德克斯特問他應該怎麼去做。那麼,我會創建一個擴展。

static class DateTimeExtensions 
{ 
    public static string ToString(this DateTime? dateTime, string format) 
    { 
     return dateTime.HasValue ? dateTime.Value.ToString(format) : String.Empty; 
    } 
} 

然後你就可以這樣做:

DateTime? dt = null; 
DateTime? dt2 = DateTime.Now; 
Console.WriteLine(dt.ToString("dd-MM-yy")); 
Console.WriteLine(dt2.ToString("dd-MM-yy")); 

注意,我可以調用擴展方法上可空類型,如果對象爲null。

+0

這是一個不錯的解決方案 – 2013-11-01 13:06:36

相關問題