2012-01-05 19 views
5

Her zaman kullandığım aynı kodu yeniden kullanmaya çalışıyorum ama şimdi bir hatayla karşılaşıyor.Nullable Nesne bir değere sahip olmalıdır # 2

Ben çeşitli kullanıcı tablolar arasında döngü ediyorum ve orada bunu: döngü içinde

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

. yerine önce gelir "dcdt" nin,

System.InvalidOperationException: Nullable object must have a value. 

hata olayları "lldt" satırı: hatası alıyorum. Bu kendi içinde garip. Veritabanındaki bu alanların her ikisi de "boş değerlere izin ver" işaretlidir. Ve her ikisi de boş olabilir ya da null olmayabilir.

İki değer de DateTime olarak listeleniyor mu? intellisense yoluyla türler.

Neden ASP.NET'in boş tarihler için boş çıktı izin vermeyi reddettiğini anlamıyorum. Boş/boşsa, mantık ASP.NET'in hiçbir şey yazdırmaması gerektiğini önerir.

NULL tarihi nasıl çıktı? Sıfır DateTimes yayınlamaya çalışmamayı engelleyen ifadeler ekledim ancak yardımcı olmadı, hiçbir anlamı yok.

cevap

12

Dediğiniz gibi, u.LastLogon veri türü DateTime?'dur. Bu, bir değere sahip olabileceği veya olmayabileceği anlamına gelir. DateTime'a göndererek bir değere sahip olmanızı gerektirir. Bu durumda değil.

userRow["LastLogon"] = u.LastLogin.HasValue ? 
         (object) u.LastLogin.ToShortDateString() : DBNull.Value; 
veritabanı LastLogon kolon DateTime tiptedir

, o zaman mümkün olmalıdır:

onunla yapmaya çalıştığımız şey bağlı olarak, HasValue özelliğini kontrol etmek isteyebilirsiniz Yapılması gerekenler:

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

Peki bu konuda ne yapıyorum? Ben oynamam mı? DateTime'daki ShortDateString() kullanmaya devam mı ediyorum? DateTime yerine? – Dexter

+0

Sütun türü DateTime –

+1

ise güncellememi görün. U.LastLogon.Value.ToShortDateString() 'işlevi nasıl değil? –

1

Sorun, .NET null, SQL NULL ile aynı değil. SQL Boş, System.DBNull. Yani, .NET'te [null] değeri değil.

+0

Peki ya bir şey yazdırmamalı ya da varsa bir tarih basacak şekilde nasıl yapabilirim? – Dexter

+0

Teknik olarak Frazell doğru, ancak çeviri otomatik olarak gerçekleşir eminim. Tarih saat sütununuz boşsa, bir .net boş göreceksiniz. Ama sorun değil, boş olup olmadığını kontrol etmek için bir kod yazmanız gerekmiyor. Gördüğünüz gibi, bunu yapmak için en kompakt yolu ile? ASP.NET bunu sizin için yapmayacaktır. –

1

Görünüşe bir DateTime üzerinde bir yöntem (dcdt.ToShortDateString()) aramak çalıştığınız gibi? bir değeri olmayan (aslında, null). Bu deneyin:

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

EDIT (Sadece soruyu tekrar okumak): Ayrıca, DateTime dönüştürmek çalışmayın. Nullable'ı koru.

DÜZENLEME 2. (açıklamalara dayanarak):

bu deneyin:

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

ise:

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

u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString(): DBNull.Value; veya u.LastLogon.HasValue? u.LastLogon.ToShortDateString(): DBNull.Value; çalışmayı reddeder. Böyle derleme yapmaz. LastLogon bir DateTime türüdür. – Dexter

+0

Bu nedenle, DBNull.Value bir dize olmadığından, ifade tutarlı bir veri türü döndürmelidir. Uygun şekilde düzenleyeceğim –

+0

Sanırım çözdüm. Bunu kullandım: userRow ["LastLogon"] = u.LastLogon.HasValue? u.LastLogon.Value.ToShortDateString(): String.Empty; – Dexter

1

Sen veri erişim kodunu aşağıdaki gibi bir şey yapmak gerekir döndürülen sütun NULL, bir System.DBNull olarak döndürülür, aksi takdirde DateTime örneği olarak döndürülür (veya uygun eşlenen türün ne olursa olsun — int, string, vb.).Sonuç olarak, yayınlamaya çalışmadan önce sorgudan döndürülen nesnenin türünü denetlemeniz gerekir.

+0

Zaten DateTime? yazın. Şimdi DateTime sınıfında ShortDateTimeString işlevini kullanarak bir String'e dönüştürmek istiyorum. Bana izin vermeyecek. – Dexter

+1

Bu durumda, 'string s = instance.HasValue? example.Value.ToString(): ""; ”hile yapmalı. –

+0

Evet, doğru. Ama bir başkası sizi doğru formatta cevaplamak için harcadı. – Dexter

1

Dexter'ın bunun hakkında nasıl bir şey yapması gerektiğini sorduğunu gördüm. Eh, bir uzantı oluştururdum.

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

Ve sonra yapabilirsiniz: nesne null ise bir null tipine uzatma yöntemini çağırabilirsiniz

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

Not.

+0

bu güzel bir çözüm –

İlgili konular