Announcement

Collapse
No announcement yet.

DataColumn: Werte zuweisen und abfragen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DataColumn: Werte zuweisen und abfragen

    Hallo,
    trotz aller Erläuterungen und Beispiele verstehe ich noch nicht, wie "beliebige" Werte einem Feld in tbl = DataSet.Tables[xxx] zugewiesen und abgefragt werden können. Die Beispiele beziehen sich fast immer auf Strings und sind (auch mir) dann klar, aber sonst?
    Bei der Bestimmung einer bestimmten Spalte in einer Zeile einer Tabelle habe ich keine Probleme:
    foreach(DataRow dr in tbl) { ... }
    // <b>(1) Boolean</b>
    // (a) Zuweisung klappt
    dr["Zulaessig"] = true;
    // (b) Abfrage klappt so nicht:
    if (dr["Zulaessig"]) { ... }
    // muss ich wirklich wie folgt arbeiten (ob das gewünschte Ergebnis dann kommt, habe ich noch nicht ausprobiert)?!
    if ( Convert.ToBoolean(dr["Zulaessig"].ToString()) ) { ... }
    // <b>(2) Integer, DateTime usw.</b>
    Hier wäre die explizite oder implizite Konvertierung ähnlich umständlich.
    Unter <u>Delphi</u> konnte ich zunächst die Art des Feldes feststellen (das geht hier mit DataType natürlich auch) und dann gezielt mit <u>AsBoolean</u> usw. zugreifen - und so etwas finde ich nicht.
    Wie macht man das am kürzesten? Danke für Hinweise (oder Verweis auf Beispiele in der NET-SDK-Dokumentation)!
    Jürgen

  • #2
    Hallo,
    das .NET Framework unterscheidet an dieser Stelle zwischen dem untypisierten und dem typisierten DataSet. Bei einem untypisierten DataSet müssen alle <i>object</i>-Werte über eine explizite Typumwandlung in eigener Regie angesprochen werden. Sobald jedoch ein typisiertes DataSet generiert wird (entweder über die IDE oder über das <i>Microsoft Xml Schemas/DataTypes support utility</i> XSD.EXE), kapselt eine <b>automatisch generierte</b> Hilfsklasse alle Spalten der Tabelle in objektorientierter Art und Weise ein. Das sieht am Beispiel einer Tabellenspalte vom Typ DATETIME zum Beispie so aus:

    <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border-top: windowtext 1pt solid; padding-top: 0pt; border-left: windowtext 1pt solid; padding-left: 0pt; border-right: windowtext 1pt solid; padding-right: 0pt; border-bottom: windowtext 1pt solid; padding-bottom: 0pt;"><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [System.Diagnostics.DebuggerNonUserCodeAttribute()]</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> System.<span style="color: teal;">DateTime</span> archivdatum {</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">get</span> {</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> ((System.<span style="color: teal;">DateTime</span>)(<span style="color: blue;">this</span>[<span style="color: blue;">this</span>.tableDateiArchiv.archivdatumColumn]));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">set</span> {</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>[<span style="color: blue;">this</span>.tableDateiArchiv.archivdatumColumn] = <span style="color: blue;">value</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div>
    <br>
    Das typisierte DataSet berücksichtigt auch automatisch den NULL-Sonderfall, in dem für jede Spalte der Tabelle die Eigenschaft Is<i>Spaltenname</i>Null generiert wird:

    <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border-top: windowtext 1pt solid; padding-top: 0pt; border-left: windowtext 1pt solid; padding-left: 0pt; border-right: windowtext 1pt solid; padding-right: 0pt; border-bottom: windowtext 1pt solid; padding-bottom: 0pt;"><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [System.Diagnostics.DebuggerNonUserCodeAttribute()]</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">public</span> <span style="color: blue;">bool</span> IsstatusNull() {</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> <span style="color: blue;">this</span>.IsNull(<span style="color: blue;">this</span>.tableDateiArchiv.statusColumn);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div>

    Sobald das typisierte DataSet verwendet wird, greift auch die Programmierhilfe (IntelliSence von Visual Studio), da dann alle Spalten der Tabelle zur Auswahl angeboten werden. Außerden sind in der Hilfsklasse des typisierten DataSets auch zahlreichen vordefinierte Methoden für die im Alltag anfallenden Standardaufgaben enthalten

    Comment


    • #3
      Danke, Herr Kosch,
      auf diesem Weg werden mir die Vorteile von typisierten DataSets klar - und es wird auch deutlich, dass die Borland-IDE nicht genügend hilft.
      Aber auf dem Umweg über WriteXmlSchema und xsd.exe komme ich dann wohl doch zum einfachen Zugriff.
      Recht herzlichen Dank - was würden wir ohne Sie erreichen!
      Jürgen Thoma

      Comment


      • #4
        Hallo Jürgen,
        Du kannst mit C# aber auch ohne ein typisiertes DataSet (fast) direkt auf die Werte zugreifen, genau wie unter Delphi.
        Vorausgesetzt Du kennst den Feldtyp und der Inhalt ist nicht NULL.
        Denn dann kanst Du, wie auch in Delphi, einen hardcodierten TypeCast durchführen:

        if ((bool)dr["Zulaessig"])
        ....
        oder

        if ((DateTime)dr["ErstellungsDatum"])
        ...

        Das ganze solltest Du aber sicherheitshalber in einen try/catch-Block packen. Sonst kracht es, wenn mal nicht der erwartetet Typ in dem Feld steht.

        Gruß
        Carste

        Comment


        • #5
          @Carsten
          Ich hatte wegen späterer Verwendung eine zusätzliche Variable eingeschaltet; damit hatte es nicht funktioniert:
          <i>col = dr["Changed"] as DataColumn;
          if ((bool)col) { ... }
          error CS0030: Konvertierung des Typs System.Data.DataColumn' zu 'bool' nicht möglich.</i>
          Aber die direkte Verwendung funktioniert tatsächlich:
          <i>if ((bool)dr["Changed"]) { ... }</i>
          Das Verfahren von Andreas Kosch ist aber wohl doch sicherer und konsequenter und deshalb besser.
          @Herrn Kosch
          DateTime wird allerdings nicht direkt verarbeitet:
          <b>ungültiger primitiver Typ: System.DateTime. </b><i>Es können nur mit CLS kompatible primitive Typen verwendet werden. Verwenden Sie CodeObjectCreateExpression.</i>
          Nach Ihrem Fragment wäre das möglich. Aus der Dokumentation zu CodeObjectCreateExpression kann ich aber nicht erkennen, wie ich auch DateTime-Felder registrieren lassen kann.
          <b><u>Zusatzfrage für Date-Felder:</b></u> Oft benötige ich nur den Datumswert (bei Delphi also integer von etwa 35000).
          Muss ich dazu Datum.Ticks / 1000000000000 oder so berechnen (dazu wäre eine statische Methode möglich), oder gibt es eine einfachere Konvertierung unter NET von DateTime nach int?
          Bitte helfen Sie mir weiter! Danke schön!
          Jürge

          Comment

          Working...
          X