Was ist die beste Praxis null int / char aus einer SQL-Datenbank für den Umgang mit?

StackOverflow https://stackoverflow.com/questions/318567

  •  11-07-2019
  •  | 
  •  

Frage

Ich habe eine Datenbank, das ist ein optionales Profil des Benutzers zu halten. Im Profil habe ich Strings, char (für M oder F) und ints.

ich in ein Problem lief, wo ich versuche, das Geschlecht des Benutzers in das Eigentum meines Profilobjekt zu setzen, und die Anwendung abstürzt, weil sie nicht wissen, wie ein zurück Null-Wert zu behandeln.

Ich habe versucht, die Daten in dem entsprechenden Typ Gießen

char sex = (char)dt.Rows[0]["Sex"];

Welche beheben nicht mein Problem. Ich habe dann versucht, die Typen und Nullable Nullable Veränderung und erhalten Sie alle Konvertierungsprobleme gleich. Meine aktuelle Lösung, die ich finden konnte ist die folgende:

object.sex = null;  
if(dt.Rows[0]["Sex"] != DBNull.Value)
      object.sex = (char)dt.Rows[0]["Sex"];
object.WorkExt = null;
if(dt.Rows[0]["WorkExt"] != DBNull.Value)
      object.WorkExt = (int)dt.Rows[0]["WorkExt"];

Gibt es eine einfachere oder bessere Art und Weise, dies zu tun? Oder bin ich ziemlich auf dem richtigen Weg?

War es hilfreich?

Lösung

Rotard Antwort (Verwendung Is<ColumnName>Null()) funktioniert nur für typisierte Datensätze.

Für nicht typisierte Datensätze, haben Sie eines der Muster in den folgenden Code zu verwenden. Wenn dieser Code nicht endgültig ist, lassen Sie mich wissen, und ich werde es bearbeiten, bis es ist. Dies ist eine sehr häufige Frage, dass es wirklich nur eine richtige Antwort sein sollte.

using System.
using System.Data;

class Program
{
    static void Main(string[] args)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("test", typeof (char));
        dt.Columns["test"].AllowDBNull = true;

        DataRow dr = dt.Rows.Add();
        char? test;

        try
        {
            test = (char?)dr["test"];
        }
        catch (InvalidCastException)
        {
            Console.WriteLine("Simply casting to a nullable type doesn't work.");
        }

        test  = dr.Field<char?>("test");
        if (test == null)
        {
            Console.WriteLine("The Field extension method in .NET 3.5 converts System.DBNull to null.");                
        }

        test = (dr["test"] is DBNull) ? null : (char?) dr["test"];
        if (test == null)
        {
            Console.WriteLine("Before .NET 3.5, you have to check the type of the column's value.");
        }

        test = (dr["test"] == DBNull.Value) ? null : (char?) dr["test"];
        if (test == null)
        {
            Console.WriteLine("Comparing the field's value to DBNull.Value is very marginally faster, but takes a bit more code.");
        }

        // now let's put the data back

        try
        {
            dr["test"] = test;
        }
        catch (ArgumentException)
        {
            Console.WriteLine("You can't set nullable columns to null.");
        }

        dr.SetField("test", test);
        if (dr["test"] is DBNull)
        {
            Console.WriteLine("Again, in .NET 3.5 extension methods make this relatively easy.");
        }

        dr["test"] = (object)test ?? DBNull.Value;
        if (dr["test"] is DBNull)
        {
            Console.WriteLine("Before .NET 3.5, you can use the null coalescing operator, but note the awful cast required.");
        }


        Console.ReadLine();
    }
}

Andere Tipps

Nullable Types wurden speziell für diesen Zweck! verwenden ‚als Zeichen?‘ anstelle von "(char?)

class Foo {
    char? sex;
}
Foo object;

object.sex = dt.Rows[0]["Sex"] as char?;

Eine anständige Diskussion zu diesem Thema ist unter effizienteste Weg für DBNull zu prüfen und dann zu einer variablen zuweisen? .

Ist dt eine ADO.Net 2 Datentabelle? Können Sie sich nicht wie etwas tun:

if(dt.Rows[0].IsSexNull()) {} else {}

? Auch unter der Annahme Sie die Kontrolle über Ihre Datenbank haben, wäre es nicht mehr Sinn machen, ein bisschen zu verwenden, anstatt ein String?

, wie etwa:

    internal static T CastTo<T>(object value)
    {
        return value != DBNull.Value ? (T)value : default(T);
    }

und dann verwenden Sie es mögen:

        return new EquipmentDetails(
            CastTo<int>(reader["ID"]),
            CastTo<int>(reader["CategoryID"]),
            CastTo<string>(reader["Description"]));

etc ...

Ich würde es tun, ziemlich genau wie Sie getan haben. Ich würde eine Funktion für sie schreiben:

Etwas, das tut:

object.sex = handle(dt.Rows[0]["Sex"]);

Und in Griff tun Sie das == DBNull.Value überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top