1

将 sql 中的日期时间字段读入数据表时出现以下问题。
查询工作正常,但是当我进入 foreach 循环时,它抱怨 datetime 字段中有一个空值。

我有一个类定义为:

public class trading_book_product_IRS        
    {
        public DataTable dt_IRS { get; set; }

        public string account_deal_position_id { get; set; }
        public DateTime schedule_start_date { get; set; }
        public DateTime schedule_end_date { get; set; }
        public string repricing_type { get; set; }
        public string coupon_type { get; set; }
        public string reference_curve { get; set; }
        public string reference_curve_point { get; set; }
        public decimal interest_rate { get; set; }
        public decimal interest_rate_spread { get; set; }        
}

我使用以下方法创建了我的数据表,因为我是这样做的,所以我不能使用DateTime

public static DataTable CreateDataTable(Type animaltype)
    {
        DataTable return_Datatable = new DataTable();
        foreach (PropertyInfo info in animaltype.GetProperties())
        {
            if (!info.Name.StartsWith("dt_"))
            {
                return_Datatable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
            }
        }
        return return_Datatable;
    }

然后我进行查询并期望写入结果,但是我无法处理 DateTime 为空。我正在尝试做的是:如果日期时间为空,则将日期设为 99990101。问题在于 schedule_end_date 和 schedule_start_date 字段。

 var query =
            from result in t_sdi_trading_book_product_interest_repricing_schedule_hsbc.AsEnumerable()
            where result.sdi_control_id == sdi_id
            && accountDealIDs.Contains(result.account_deal_position_id)
            select new trading_book_product_IRS()
            {
                account_deal_position_id = result.account_deal_position_id,
                coupon_type = result.coupon_type,
                interest_rate = result.interest_rate,
                interest_rate_spread = result.interest_rate_spread,
                reference_curve = result.reference_curve,
                reference_curve_point = result.reference_curve_point,
                repricing_type = result.repricing_type,
                schedule_end_date = !string.IsNullOrEmpty(result.schedule_end_date.ToString()) ? result.schedule_end_date : DateTime.Parse("99990101"),
                schedule_start_date = !string.IsNullOrEmpty(result.schedule_start_date.ToString()) ? result.schedule_start_date : DateTime.Parse("99990101"),
            };

        foreach (var results in query)
        {
            foreach (PropertyInfo result in results.GetType().GetProperties())
            {

                string name = result.Name;

                foreach (PropertyInfo info in used.GetType().GetProperties())
                {
                    if ((result.Name == info.Name) && (!result.Name.StartsWith("dt_")))
                    {
                        try
                        {
                            info.SetValue(used, result.GetValue(results, null), null);
                        }
                        catch (NoNullAllowedException e)
                        {
                        }

                    }
                }
            }
            dt_IRS.Rows.Add(makeRow(used, dt_IRS));
        }
4

5 回答 5

2

您的问题是您的投影是否或是否总是会schedule_end_date抛出异常,因为您尝试调用该属性,无论它是否已分配。schedule_start_datenullToString

你需要做类似的事情

schedule_end_date = result.schedule_end_date ?? DateTime.Parse("..."),
schedule_start_date = result.schedule_start_date ?? DateTime.Parse("...")


更新

基于result.schedule_end_date/result.schedule_start_date实际上不能为空的启示,那么您实际上根本无法检查日期是否存在null。最有可能的是,如果数据null位于 DB 端,那么某些东西正在nullDateTime.

大多数 ORM 将转换nullDateTime.MinValue.


鉴于您使用的是 Linq to SQL,您还需要在属性中设置属性CanBeNull,即trueColumn

[Column(CanBeNull=true)]
public DateTime? schedule_start_date;

[Column(CanBeNull=true)]
public DateTime? schedule_end_date;

然后你可以使用空合并运算符来设置你的默认值,即

schedule_end_date = result.schedule_end_date ?? DateTime.ParseExact("yyyyMMdd", "99990101", CurrentCulture.InvariantCulture),
schedule_start_date = result.schedule_start_date ?? DateTime.ParseExact("yyyyMMdd", "99990101", CurrentCulture.InvariantCulture),
于 2013-09-17T13:09:19.550 回答
1

尝试使用

schedule_end_date = result.schedule_end_date ?? 
                    DateTime.Parse( // A valid string date );
于 2013-09-17T13:00:37.257 回答
1

使用没有什么问题nullable。只需更改您的CreateDataTable功能以应对它。

public class trading_book_product_IRS        
{
    public DataTable dt_IRS { get; set; }
    public string account_deal_position_id { get; set; }
    public DateTime? schedule_start_date { get; set; }
    public DateTime? schedule_end_date { get; set; }
    public string repricing_type { get; set; }
    public string coupon_type { get; set; }
    public string reference_curve { get; set; }
    public string reference_curve_point { get; set; }
    public decimal interest_rate { get; set; }
    public decimal interest_rate_spread { get; set; }        
}

public static DataTable CreateDataTable(Type type)
{
    var dataTable = new DataTable();
    foreach (PropertyInfo info in type.GetProperties())
    {
        if(info.PropertyType == typeof(DataTable)) continue;

        DataColumn column;

        var type = Nullable.GetUnderlyingType(info.PropertyType);

        if(type != null)
        {
            column = new DataColumn(info.Name, type)
        }
        else
        {
            column = new DataColumn(info.Name, info.PropertyType);
        }

        dataTable.Columns.Add(column);
    }

    return dataTable;
}

在 linq 内部:

schedule_end_date = result.schedule_end_date
schedule_start_date = result.schedule_start_date
于 2013-09-17T13:24:26.260 回答
0

像这样的东西可能会起作用:

result.schedule_end_date == null ? result.schedule_end_date : DateTime.Parse("01/01/1900")
于 2013-09-17T13:08:39.763 回答
-2

你用过吗

Nullable<DateTime>

编辑:我不会把它记下来,因为我天真地认为我是不同的,Nullable<DateTime>并且DateTime?编译器对它的解释不同。原来DateTime?是以前版本的简写。只是为其他不知道的人提供参考......我将接受反对票。

于 2013-09-17T12:57:02.153 回答