2012-01-05 24 views
5

私はいつも使っていたのと同じコードを再利用しようとしていますが、今はエラーが発生しています。Nullableオブジェクトは値#2を持つ必要があります

私は、様々なユーザーテーブルをループしていて、そこに私はこれを行う:ループ内

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

System.InvalidOperationException: Nullable object must have a value. 

エラーのハイライト "LLDT" ライン、代わりに最初に来る "DCDT" の:私はエラーを取得します。それはそれ自体で奇妙です。データベース「allow nulls」のこれらのフィールドが両方ともチェックされます。両方ともnullでもよいし、どちらもnullでもかまいません。

2つの値の両方がDateTimeとして表示されますか?インテリセンスを介してタイプします。

なぜ、ASP.NETがnullの日付に空白を出力することを許可しないのか分かりません。それが空白/ nullの場合、ロジックはASP.NETが何も印刷しないことを示唆します。

他にどのようにヌル日付を出力するとしますか?私はnullのDateTimesをキャストしようとするのを防ぐためにif文を追加しようとしましたが、それは役に立たず、意味がありません。

答えて

12

あなたが言ったように、u.LastLogonのデータタイプはDateTime?です。つまり、値がある場合とない場合があります。 DateTimeにキャストすると、値が必要です。この場合、それはしません。

あなたがそれで何をしようとして、あなたはHasValueプロパティをチェックすることもできますによって:

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

データベースLastLogon列がのDateTime型である場合、あなたはできるはずです行うこと:あなたがDateTimeの上の方法(dcdt.ToShortDateString())を呼び出すようにしようとしているよう

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

どうすればいいですか?私はキャストしませんか? DateTimeでShortDateString()を使用し続けますか? DateTimeの代わりに? – Dexter

+0

カラムタイプがDateTime –

+1

の場合、私の更新を見てください。 'u.LastLogon.Value.ToShortDateString()'はどうやって動かないのですか? –

1

問題は.NET nullはSQL NULLと同じではありません。 SQL NullはSystem.DBNullです。したがって、.NETでは[null]という値になります。

+0

それでは、何も印刷しないでください、または、利用可能であれば、日付を印刷するようにするにはどうすればよいですか? – Dexter

+0

技術的にはFrazellは正しいですが、翻訳が自動的に行われることは間違いありません。 datetimeカラムがnullの場合、.net nullが表示されます。しかし、それは問題ではない、あなたはそれがnullであるかどうかをチェックし、何も印刷していないことを確認するコードを書く必要がある。あなたが見たように、これを行うための最もコンパクトな方法は? ASP.NETはあなたのためにこれを行いません。 –

1

が見えますか?値を持たない(実際にはnullです)。

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

EDIT(ジャスト再読み込み質問):これを試してみてください。また、日時に変換しようとしないでください。 null値を保持します。 (コメントに基づいて)

EDIT#2:場合

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

:あなたはあなたのデータ・アクセス・コードに次のような何かをする必要があり

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

+0

DBNull.Valueは文字列ではないため、式は一貫したデータ型を返す必要があります。私は適切に編集します –

+0

私はそれを解決したと思います。私はこれを使いました:userRow ["LastLogon"] = u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString():String.Empty; – Dexter

1

これを試してみてください返される列がNULLの場合、System.DBNullとして返されます。それ以外の場合は、DateTimeのインスタンスとして返されます(または適切なマップ型が— int、stringなど)。したがって、キャストする前に、クエリから返されるオブジェクトのタイプをチェックする必要があります。

+0

これは既にDateTimeですか?タイプ。今私はDateTimeクラスのShortDateTimeString関数を使用してStringに変換します。それは私を許さないでしょう。 – Dexter

+1

その場合、 'string s = instance.HasValue? instance.Value.ToString(): "";このトリックを行う必要があります。 –

+0

はい、正しいです。しかし、他の誰かがちょっと正しい形式で答えにあなたを打つ。 – Dexter

1

私はデクスターが彼がそれについてどうやって行くべきか尋ねた。さて、私は拡張を作成します。

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

そして、あなたが行うことができます:オブジェクトがnullの場合、私はNULL可能タイプに拡張メソッドを呼び出すことができます

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

注意。

+0

これは素晴らしい解決策です –

関連する問題