验证空值转换

时间:2010-02-25 17:57:08

标签: c#

我有一个名为project的类,其中包含以下数据成员。

class Project
{
    private int Record_Num;
    private int GCD_ID;
    private string Project_Desc;
    private string Proponent_Name;
    private string Station_ID;
    private string OpCentre;
    private string Sector_ID;
    private string PLZone;
    private string Feeder_ID;
    private string DxTx_ID;
    private string OpControl_ID;
    private string Type_ID;
    private string ConnKV_ID;
    private string Status_ID;
    private double MW;
    private string Subject;
    private int Ip_Num;
    private int H1N_ID;
    private int NOMS_Slip_Num;
    private DateTime NMS_Updated;
    private DateTime Received_Date;
    private Nullable<DateTime> Actual_IS_Date;
    private string Scheduled_IS_Date;
    private string UP_Station_ID;
    private string UP_Feeder_ID;
    private string HV_Circuit;
}

我查询数据库并通过数据表检索值,该数据表将值分配给项目对象。

for (int prjIdx = 0; prjIdx < dt.Rows.Count; prjIdx++)
            {
                newProject = new Project(Convert.ToInt32(dt.Rows[prjIdx]["RecordNum"].ToString()), Convert.ToInt32(dt.Rows[prjIdx]["GCDID"].ToString()),
                    dt.Rows[prjIdx]["ProjectDesc"].ToString(), dt.Rows[prjIdx]["ProponentName"].ToString(),
                    dt.Rows[prjIdx]["StationName"].ToString(), dt.Rows[prjIdx]["OpCentre"].ToString(),
                    dt.Rows[prjIdx]["SectorName"].ToString(), dt.Rows[prjIdx]["PLZone"].ToString(),
                    dt.Rows[prjIdx]["FeederDesc"].ToString(), dt.Rows[prjIdx]["DxTx"].ToString(),
                    dt.Rows[prjIdx]["OpControl"].ToString(), dt.Rows[prjIdx]["Type"].ToString(),
                    dt.Rows[prjIdx]["ConnectionKV"].ToString(), dt.Rows[prjIdx]["Status"].ToString(),
                    Convert.ToDouble(dt.Rows[prjIdx]["MW"]), dt.Rows[prjIdx]["Subject"].ToString(),
                    Convert.ToInt32(dt.Rows[prjIdx]["IpNum"]), Convert.ToInt32(dt.Rows[prjIdx]["H1NID"]),
                    Convert.ToInt32(dt.Rows[prjIdx]["NomsSlipNum"]),Convert.ToDateTime(dt.Rows[prjIdx]["NmsUpdated"]),
                    Convert.ToDateTime(dt.Rows[prjIdx]["ReceivedDate"]),Convert.ToDateTime(dt.Rows[prjIdx]["ActualIsDate"]),
                    dt.Rows[prjIdx]["ScheduledIsDate"].ToString(),dt.Rows[prjIdx]["UpStation"].ToString(),dt.Rows[prjIdx]["UpFeeder"].ToString(),
                    dt.Rows[prjIdx]["HVCircuit"].ToString());

                newProject.record_num = Convert.ToInt32(dt.Rows[prjIdx]["RecordNum"]);
                projList.Add(newProject);

            }

现在我的问题是,从数据库中检索的所有日期时间值都可以为null。如果遇到空值,则无法转换它,因此无法将其分配给对象。因此它给我一个错误

我该如何解决问题。 我应该将日期时间变量更改为字符串数据类型。但这是一个蹩脚的解决方案。请帮助//

5 个答案:

答案 0 :(得分:4)

DateTime是一个值类型,您可以使用可为空的日期时间(DateTime?

MSDN Ref on Nullable Structure

[...]
private int NOMS_Slip_Num;
private DateTime? NMS_Updated;
private DateTime? Received_Date;
private Nullable<DateTime> Actual_IS_Date;
[...]

这样做需要更改检索值的方式。一种方法是实现nullDBNull检查,并使用三元运算符在Project instanciation中设置可空日期时间的值。

public static class Extensions
{
    public static bool IsNull(this object o)
    {
        if (o == null || DBNull.Value.Equals(o))
            return true;
        else
            return false;
    }
}

并在Project的instanciation中使用它:

var receivedDate = dt.Rows[prjIdx]["ReceivedDate"];
var actualDate = dt.Rows[prjIdx]["ActualIsDate"];
newProject = new Project([...],
                       receivedDate.IsNull() ? null : Convert.ToDateTime(receivedDate),
                       actualDate.IsNull() ? null : Convert.ToDateTime(actualDate),
                       [...]);

答案 1 :(得分:1)

众所周知,您可以在模型中使用Nullable Types。至于让他们走出行并检查DBNull,MS已经足够聪明地考虑到这一点,并提供了一组扩展方法来做到这一点。

DataRowExtensions.Field Method

...  
dt.Rows[prjIdx].Field<Int32?>("IpNum");  
...

只要你的底层类型实际上是一个int,那么这就行了。

  

Field方法不执行类型   转换。如果是类型转换   要求,你应该先获得   使用Field的列值   方法。然后应该列值   转换为另一种类型。

答案 2 :(得分:0)

更改为可以为空的DateTime。

答案 3 :(得分:0)

我喜欢保留此实用程序类来处理DBNull值

public static class DBNullConvert
{
    public static T To<T>(object value, T defaultValue)
    {
        T cast;

        try
        {
            cast = value == DBNull.Value ? defaultValue : (T)value;
        }
        catch
        {
            throw new ArgumentException(string.Format("Argument of type {0} cannot be cast to type {1}", value.GetType(), typeof(T)), "value");
        }

        return cast;
    }

    public static T To<T>(object value)
    {
        return To(value, default(T));
    }

    public static T? ToNullable<T>(object value) where T : struct
    {
        T? cast;

        try
        {
            cast = value == DBNull.Value ? null : (T?)value;
        }
        catch
        {
            throw new ArgumentException(string.Format("Argument of type {0} cannot be cast to type {1}", value.GetType(), typeof(T?)), "value");
        }

        return cast;
    }

    public static string ToString(object value)
    {
        return To(value, String.Empty);
    }
}

然后你可以像这样使用它:

DBNullConvert.ToNullable<DateTime>(dt.Rows[prjIdx]["ReceivedDate"])

如果字段为DBNull.Value,则返回null;如果有字段,则返回存储在字段中的日期时间。

答案 4 :(得分:0)

正如Dynamy所说,你可以使用

的DateTime?这是一个Nullable类型的日期。

Nullable Type C#

<磷>氮