Reputation: 858
I have a class named project with the following data members.
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;
}
i query the database and retrieve the values through a data table which assigns the value to the project object like this.
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);
}
now my problem is, all the date time values retrieved from the database can be null.so if it encounters a null value, it fails to convert it and hence it cannot be assigned in to the object. thus it give me an error
how do i tackle the proble. should i change the date time variable to string data type. but thats a lame solution. please help//
Upvotes: 1
Views: 663
Reputation: 5036
DateTime
is a value-type, you could use the nullable 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;
[...]
Doing so will require changes in how you retrieve the value. One way to do so, would be to implement a null
or DBNull
check, and set the value of nullable datetimes in the Project instanciation using a ternary operator.
public static class Extensions
{
public static bool IsNull(this object o)
{
if (o == null || DBNull.Value.Equals(o))
return true;
else
return false;
}
}
and use it like this in Project's 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),
[...]);
Upvotes: 4
Reputation: 44916
As everyone has already stated you can use Nullable Types in your Model. As for getting them out of the row and checking for DBNull, MS was smart enough to think of this already, and provided a set of extension methods to do just that.
DataRowExtensions.Field Method
...
dt.Rows[prjIdx].Field<Int32?>("IpNum");
...
As long as your underlying type is in fact an int, then this will do the trick.
The Field method does not perform type conversions. If type conversion is required, you should first obtain the column value by using the Field method. The column value should then be converted to another type.
Upvotes: 1
Reputation: 179
As Dynamy stated you can use the
DateTime? which is a Nullable type of date.
N.
Upvotes: 0
Reputation: 19214
I like to keep this utility class around for dealing with DBNull values
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);
}
}
Then you can use it like this:
DBNullConvert.ToNullable<DateTime>(dt.Rows[prjIdx]["ReceivedDate"])
which will return null if the field is DBNull.Value or the datetime stored in the field if there is one.
Upvotes: 0