2010-10-28 7 views
5

Ich sah this thread auf Stack-Überlauf in Bezug auf zwischen DBNull und Nullable Types Umwandlung, aber ich bin immer noch verwirrt. Ich habe mit einigem Hack Code Code wie folgt geschrieben mit Nullable Types für Datetime zu beschäftigen und ints, dass ich unten zeigen würde, aber es ist ein Chaos, und ich will Nullable-Typen verwenden:Ärger mit Nullable Types, DBNulls und Datenzeilen

DataTable dt = ds.Tables[0]; 
List<RON> list = (from dr in dt.AsEnumerable() 
           select new RON 
           { 
            RONId = dr[0].ToString(), 
            StaffNumber = dr[1].ToString(), 
            CheckInDate = GetCheckInDate(dr[2]), 
            NonMissionIndicator = dr[3].ToString(), 
            Comments = dr[4].ToString(), 
            NonComplyIndicator = dr[5].ToString(), 
            LOAirport = dr[6].ToString(), 
            RONAirport = dr[7].ToString(), 
            PropertyId = GetPropertyId(dr[8]), 
            PropertyChain = dr[9].ToString(), 
            PropertyName = dr[10].ToString(), 
            PropertyStreet = dr[11].ToString(), 
            PropertyStreet2 = dr[12].ToString(), 
            PropertyCity = dr[13].ToString(), 
            PropertyState = dr[14].ToString(), 
            PropertyPostalCode = dr[15].ToString(), 
            PropertyPhone = dr[16].ToString(), 
            FAX = dr[17].ToString(), 
            PropertyCountry = dr[18].ToString(), 
            PropertyLongitude = GetPropertyLongitude(dr[19]), 
            PropertyLatitude = GetPropertyLatitude(dr[20]), 
            PropertyAirport = dr[21].ToString(), 
            ReportedBy = dr[22].ToString(), 
            ReportedDTS= GetReportedByDate(dr[23]), 
            CanceledBy = dr[24].ToString(), 
            CanceledDTS = GetCanceledByDate(dr[25]) 
           }).ToList(); 
      return list; 
     } 

     //TODO: Change Defaukt date 
     private static DateTime GetCheckInDate(object checkInDate) 
     { 
      return checkInDate == DBNull.Value ? new DateTime(2000, 1, 1, 00, 00, 00) : Convert.ToDateTime(checkInDate); 
     } 

     //TODO: Change Defaukt date 
     private static DateTime GetReportedByDate(object reportedByDate) 
     { 
      return reportedByDate == DBNull.Value ? new DateTime(2000, 1, 1, 00, 00, 00) : Convert.ToDateTime(reportedByDate); 
     } 

     //TODO: Change Defaukt date 
     private static DateTime GetCanceledByDate(object canceledByDate) 
     { 
      return canceledByDate == DBNull.Value ? new DateTime(2000, 1, 1, 00, 00, 00) : Convert.ToDateTime(canceledByDate); 
     } 

     private static Int32 GetPropertyId(object propertyId) 
     { 
      return propertyId == DBNull.Value ? 0 : Convert.ToInt32(propertyId); 
     } 

     private static double GetPropertyLongitude(object propertyLongitude) 
     { 
      return propertyLongitude == DBNull.Value ? 0.0 : Convert.ToDouble(propertyLongitude); 
     } 

     private static double GetPropertyLatitude(object propertyLatitude) 
     { 
      return propertyLatitude == DBNull.Value ? 0.0 : Convert.ToDouble(propertyLatitude); 
     } 

RON ist nun wie folgt definiert:

public class RON 
    { 
     public string RONId { get; set; } 
     public string StaffNumber { get; set; } 
     public DateTime CheckInDate { get; set; } 
     public string NonMissionIndicator { get; set; } 
     public string NonComplyIndicator { get; set; } 
     public string LOAirport { get; set; } 
     public string RONAirport { get; set; } 
     public int PropertyId { get; set; } 
     public string PropertyChain { get; set; } 
     public string PropertyName { get; set; } 
     public string PropertyStreet { get; set; } 
     public string PropertyStreet2 { get; set; } 
     public string PropertyCity { get; set; } 
     public string PropertyState { get; set; } 
     public string PropertyPostalCode { get; set; } 
     public string PropertyCountry { get; set; } 
     public string PropertyPhone { get; set; } 
     public string FAX { get; set; } 
     public double PropertyLongitude { get; set; } 
     public double PropertyLatitude { get; set; } 
     public string PropertyAirport { get; set; } 
     public string ReportedBy { get; set; } 
     public DateTime ReportedDTS { get; set; } 
     public string CanceledBy { get; set; } 
     public DateTime CanceledDTS { get; set; } 
     public string Comments { get; set; } 

die Datenbank Mann mir sagt, dass dies die Rückkehr von Oracle im DataSet/Cursor ist:

RON_ID         NOT NULL VARCHAR2(40) 
STAFF_NUM         NOT NULL VARCHAR2(12) 
CHECKIN_DATE        NOT NULL DATE 
NONMISSION_IND       NOT NULL VARCHAR2(1) 
COMMENTS           VARCHAR2(4000) 
NONCOMPLY_IND          VARCHAR2(4000) 
PROPERTY_ID        NOT NULL NUMBER(38) 
PROPERTY_CHAIN          VARCHAR2(2) 
PROPERTY_NAME          VARCHAR2(255) 
RON_AIRPORT        NOT NULL VARCHAR2(3) 
PROPERTY_STREET         VARCHAR2(255) 
PROPERTY_STREET2         VARCHAR2(255) 
PROPERTY_CITY          VARCHAR2(255) 
PROPERTY_STATE          VARCHAR2(3) 
PROPERTY_POSTALCODE        VARCHAR2(255) 
PROPERTY_PHONE          VARCHAR2(20) 
PROPERTY_FAX          VARCHAR2(20) 
PROPERTY_COUNTRY         VARCHAR2(2) 
PROPERTY_LONGITUDE         NUMBER 
PROPERTY_LATITUDE         NUMBER 
PROPERTY_AIRPORT         VARCHAR2(3) 
REPORTED_BY          VARCHAR2(50) 
REPORTED_DTS        NOT NULL DATE 
CANCELED_BY          VARCHAR2(50) 
CANCELED_DTS          DATE 

Wie kann ich erklären RON mit Nullable Types und wie kann ich tun Operationen mit Nu llable Termine und so? Müssen Strings überprüft werden?

Antwort

6

Um einen Werttyp (wie Datetime) als Nullable ... Führen Sie eine der folgenden definieren:

DateTime? ReportedDTS 

ODER

Nullable<DateTime> ReportedDTS 

Referenztypen (wie String) bereits " NULL-fähig ".

Um einen Nullable-Wert aus einer DataRow erhalten Sie die Feld Erweiterungsmethode verwenden können:

DateTime? nullableDate = dataRow.Field<DateTime?>("ColumnName"); 

Das DBNull konvertiert diese automatisch auf null.

So für Ihr Beispiel kann man so etwas tun:

select new RON 
      { 
       RONId = dr.Field<string>("RON_ID"), 
       // snip... 
       CheckInDate = dr.Field<DateTime?>("CHECKIN_DATE"), 
       // snip... 
      }; 
+0

Dank! Also DateTime? nullableDate = dataRow.Feld ("ColumnName"); was wäre das in meinem Beispiel? –

+0

mein Beispiel aktualisiert .... – Dismissile

+0

Ich habe an} [System.InvalidCastException] "angegebene Ziel ungültig ist.": { "Das angegebene Ziel ungültig ist."} Daten: {} System.Collections.ListDictionaryInternal Help : null InnerException: null Nachricht: "Angegebener Cast ist nicht gültig." Quelle: "System.Data.DataSetExtensions" StackTrace: "um System.Data.DataRowExtensions.UnboxT'1.NullableField [TElem] (Objektwert) \ r \ n bei System.Data.DataRowExtensions.Field [T] (Da –

0

Da nur Werttypen Nullable gemacht werden können, werden Sie nichts zu tun haben, speziell für Streicher. Primitive Typen (und DateTime) durch Anhängen eines Fragezeichen nach dem Typnamen, wie int? NullableNumber { get; set; } nullable deklariert werden.

+0

Danke, das ist was ich dachte –

0

Sie müssen möglicherweise gegen DBNull vergleichen, bevor entweder ein DateTime- oder null

myNullableDate = (DBNull.Value == list.Field<object>("FOO")) 
      ? null 
      : (DateTime?)list.Field<DateTime?>("FOO"); 
0

Bei der Überprüfung Ihrer ursprünglichen Frage der Zuordnung ich sehe, dass ein Fehler tritt auf, wenn .ToString() ist hat einen Nullwert aufgerufen.

This happens when the dataset field has a DBNULL value. 
The Best approach is to test for null first before calling any methods on the object. 
i.e.

DataTable dt = ds.Tables[0]; List<RON> list = (from dr in dt.AsEnumerable() select new RON { RONId = dr.IsNull("RONid") ? "0" : dr.Field<String>("RONid"), StaffNumber = dr.IsNull("StaffNumber") ? "0" : dr.Field<String>("StaffNumber"), ... etc, ... etc }).ToList(); return list; }

PS:

  • Probe Ihr Datensatz für die Feldwerten übereinstimmen. Hier habe ich angenommen, dass das Dataset „Spaltenname“ hatte die gleichen Namen wie die Variable es übergeben wird, aber das ist nicht immer der Fall.
  • Wort Beratung, verwenden Sie „Spaltenname“ statt, da der Index der Index kann, wenn db Änderungen, gespeicherte Prozedur oder Abfrage ändert.