2

I have a database that hold's a user's optional profile. In the profile I have strings, char (for M or F) and ints.

I ran into an issue where I try to put the sex of the user into the property of my Profile object, and the application crashes because it doesn't know how to handle a returned null value.

I've tried casting the data to the appropriate type

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

Which didn't fix my problem. I then tried changing the types to Nullable and Nullable and get conversion issues all the same. My current solution that I was able to find is the following:

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"];

Is there a simpler or better way to do this? Or am I pretty much on the right track?

4

6 に答える 6

3

null 許容型は、まさにこの目的のために設計されました。'as char?' を使用しますか? 「(文字?)」の代わりに

class Foo {
    char? sex;
}
Foo object;

object.sex = dt.Rows[0]["Sex"] as char?;
于 2008-11-25T20:09:58.957 に答える
3

rotard の回答 (use Is<ColumnName>Null()) は、型指定されたデータ セットに対してのみ機能します。

型指定されていないデータ セットの場合、次のコードのいずれかのパターンを使用する必要があります。このコードが決定的なものでない場合は、私に知らせてください。そうなるまで編集します。これは非常によくある質問で、正解は 1 つしかないはずです。

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();
    }
}
于 2008-11-25T22:21:02.483 に答える
2

どうですか:

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

そしてそれを次のように使用します:

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

等...

于 2008-11-26T14:41:16.013 に答える
2

これに関する適切な議論は、 DBNull をチェックしてから変数に割り当てる最も効率的な方法ですか? .

于 2008-11-25T19:44:26.590 に答える
1

dt は ADO.Net 2 データ テーブルですか? 次のようなことはできませんか?

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

? また、データベースを制御できると仮定すると、文字列ではなくビットを使用する方が理にかなっているでしょうか?

于 2008-11-25T19:58:41.473 に答える
0

私はあなたがしたようにそれをします。私はそれのための関数を書きます:

する何か:

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

そして、ハンドルで ==DBNull.Value チェックを行います。

于 2008-11-25T19:27:48.697 に答える