2

我有一个保存用户可选配置文件的数据库。在配置文件中,我有字符串、char(用于 M 或 F)和 int。

我遇到了一个问题,我尝试将用户的性别放入我的 Profile 对象的属性中,并且应用程序崩溃了,因为它不知道如何处理返回的空值。

我已经尝试将数据转换为适当的类型

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

这并没有解决我的问题。然后我尝试将类型更改为 Nullable 和 Nullable 并得到相同的转换问题。我目前能够找到的解决方案如下:

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

有没有更简单或更好的方法来做到这一点?还是我几乎走在正确的轨道上?

4

6 回答 6

3

可空类型就是为此目的而设计的!使用“作为字符?” 而不是“(字符?)”

class Foo {
    char? sex;
}
Foo object;

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

rotard 的答案(使用Is<ColumnName>Null())仅适用于类型化的数据集。

对于无类型数据集,您必须使用以下代码中的模式之一。如果此代码不是确定的,请告诉我,我将对其进行编辑,直到确定为止。这是一个极其常见的问题,实际上应该只有一个正确答案。

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

一个体面的讨论是在检查 DBNull 然后分配给变量的最有效方法?.

于 2008-11-25T19:44:26.590 回答
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"]));

ETC...

于 2008-11-26T14:41:16.013 回答
1

dt 是 ADO.Net 2 数据表吗?你能不能做这样的事情:

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

? 此外,假设您可以控制您的数据库,使用 bit 而不是 string 是否更有意义?

于 2008-11-25T19:58:41.473 回答
0

我会像你一样做。我会为它写一个函数:

做的事情:

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

在句柄中,您执行 ==DBNull.Value 检查。

于 2008-11-25T19:27:48.697 回答