LINQ查询中DateTime为null的转换问题

时间:2012-03-06 15:21:52

标签: c# linq dataset strongly-typed-dataset linq-to-dataset

以下是我在linq查询中使用的数据表的配置: 我有2个数据集文件(所有表的所有列都指定了DataType,其AllowDbNull属性设置为True): * deposit_position_imbalance.xsd:       包含2个数据: - 不平衡                              - ImbalanceDetailForRealTime * dep_pos_imbalance_detail.xsd:       包含1个数据表: - 表

在下面的代码中,问题在于2行“deal_date = b.deal_date”。 实际上,当我从具有空值的数据库b.deal_date中检索时,它在deposit_position_imbalance.Designer.cs中说: “用户代码未处理StrongTypingException” “表'ImbalanceDetailForRealTime'中列'deal_date'的值是DBNull。” “指定演员表无效”。 这是它抛出错误的地方:


    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
            public System.DateTime deal_date {
                get {
                    try {
                        return ((global::System.DateTime)(this[this.tableImbalanceDetailForRealTime.deal_dateColumn]));
                    }
                    catch (global::System.InvalidCastException e) {
                        throw new global::System.Data.StrongTypingException("The value for column \'deal_date\' in table \'ImbalanceDetailForRealTime\' is DBNull." +
                                "", e);//ERROR THROWN HERE
                    }
                }
                set {
                    this[this.tableImbalanceDetailForRealTime.deal_dateColumn] = value;
                }
            }
  • 我试图将“deal_date = b.deal_date”替换为 “deal_date =(DateTime?)b.deal_date” 但我收到2个编译错误:“dep_pos_imbalance_detail.TableDataTable.AddTableRow(string,System.DateTime)的最佳重载方法匹配”有一些无效的参数“ 和“参数'2':无法转换'System.DateTime?'到'System.DateTime'“
  • 我还尝试将“deal_date = b.deal_date”替换为 “deal_date = b.deal_date == null?(DateTime)DBNull.Value:b.deal_date” 但我得到一个编译错误:“无法将类型'System.DBNull'转换为System.DateTime'”
  • 然后我尝试将行“deal_date = b.deal_date”替换为 “deal_date = b.deal_date == null?(DateTime?)DBNull.Value:b.deal_date” 但我得到一个编译错误:“无法将类型'System.DBNull'转换为System.DateTime?'”
  • 我尝试过另一件事:将“deal_date = b.deal_date”替换为 “deal_date = b.Isdeal_dateNull()?default(DateTime?):b.deal_date” 但同样,我有以下错误: “dep_pos_imbalance_detail.TableDataTable.AddTableRow(string,System.DateTime)'的最佳重载方法匹配'有一些无效的参数” 和“参数'2':无法转换'System.DateTime?'到'System.DateTime'“ 下面的图片(对不起,我还不允许在stackoverflow中插入图像,所以我把链接改成了)在我的数据集中显示了我的列deal_date的定义: https://lh5.googleusercontent.com/-TEZZ9Hdnkl4/T1aRxF_i7II/AAAAAAAAAAg/BwzrVXIlOHE/s323/deal_date.jpg 我们可以看到我似乎没有可能设置“System.DateTime?”但只有“System.DateTime”。而且除了默认值之外我不想要其他任何东西(为了使它工作,我们是否必须放置除默认值以外的其他东西?) UPDATE - >我试图将null设置为而不是设计者给出了这个错误:“字符串未被识别为有效的DateTime。从索引0开始有一个未知的单词。”。

所以我不明白我是如何设法检索空值的(我没有把它放在代码中,但我对double类型有同样的问题)。我的印象是我的列设置为启用空值但显然不是...... 此外,当我尝试修改NullValue属性以从“(Throw Exception)”变为“(Empty)”或“(Null)”时,设计器会给出以下错误:“输入的值对当前数据类型无效“。 谢谢您的帮助。 这是我的LINQ查询:

deposit_position_imbalance.ImbalanceDataTable dtImbalanceForRealTime;
deposit_position_imbalance.ImbalanceDetailForRealTimeDataTable dtImbalanceDetailForRealTime;

dtImbalanceForRealTime = (deposit_position_imbalance.ImbalanceDataTable)(((deposit_position_imbalance)(dataManager.GetConfig(grid1).ParentDataSource)).Imbalance);
dtImbalanceDetailForRealTime = this.detailForRealTime;

// we separate security_id null and not null
// Security id is not null
deposit_position_imbalance.ImbalanceDataTable iWithSecurityIdNotNull = new deposit_position_imbalance.ImbalanceDataTable();
deposit_position_imbalance.ImbalanceRow[] dr1 = (deposit_position_imbalance.ImbalanceRow[])dtImbalanceForRealTime.Select("security_id is not null");
if (dr1.Count<deposit_position_imbalance.ImbalanceRow>() > 0)
{
    DataTable looselyTypedDT1 = dr1.CopyToDataTable<deposit_position_imbalance.ImbalanceRow>();
    iWithSecurityIdNotNull.Merge(looselyTypedDT1, true);
}

// Security id is null
deposit_position_imbalance.ImbalanceDataTable iWithSecurityIdNull = new deposit_position_imbalance.ImbalanceDataTable();
deposit_position_imbalance.ImbalanceRow[] dr2 = (deposit_position_imbalance.ImbalanceRow[])dtImbalanceForRealTime.Select("security_id is null");
if (dr2.Count<deposit_position_imbalance.ImbalanceRow>() > 0)
{
    DataTable looselyTypedDT2 = dr2.CopyToDataTable<deposit_position_imbalance.ImbalanceRow>();
    iWithSecurityIdNull.Merge(looselyTypedDT2, true);
}

var queryWithSecurityIdFound =
    from a in iWithSecurityIdNotNull
    join b in dtImbalanceDetailForRealTime
    on new
    {
        a.situation_date,
        a.security_id,
        a.deposit_location_id,
        a.account_keeper_id
    }
        equals new
        {
            b.situation_date,
            b.security_id,
            b.deposit_location_id,
            b.account_keeper_id
        }
    where a.situation_date == situation_date
       && a.security_id == security_id
       && a.deposit_location_id == deposit_location_id
       && a.account_keeper_id == account_keeper_id
    select new
    {
        name = a.bo_source_name,
        deal_date = b.deal_date
    };

var queryWithSecurityIdNotFound =
    from a in iWithSecurityIdNull
    join b in dtImbalanceDetailForRealTime
        on new
        {
            a.situation_date,
            a.security_code,
            a.deposit_location_id,
            a.account_keeper_id
        }
        equals new
        {
            b.situation_date,
            b.security_code,
            b.deposit_location_id,
            b.account_keeper_id
        }
    where a.situation_date == situation_date
       && a.security_id == security_id
       && a.deposit_location_id == deposit_location_id
       && a.account_keeper_id == account_keeper_id
    select new
    {
        name = a.bo_source_name,
        deal_date = b.deal_date
    };

var query_final = queryWithSecurityIdFound.Union(queryWithSecurityIdNotFound);
//We fill the 'dep_pos_imbalance_detail Table'
grid1.Clear();
foreach (var item in query_final)
{
    ((dep_pos_imbalance_detail.TableDataTable)grid1.DataSet.Tables["Table"]).AddTableRow(item.name, item.deal_date);
}

2 个答案:

答案 0 :(得分:1)

如果这是strongly typed DataSet,它会自动生成您应该使用的Isdeal_dateNull等可为空的列的属性。

if (!row.Isdeal_dateNull)
{
   //do something
}

答案 1 :(得分:0)

我找到了解决问题的方法。在我的LINQ查询中,我将“deal_date = b.deal_date”替换为 “deal_date = b.Field('deal_date')”。然后可以进行转换。然后,我可以不使用Designer自动生成的方法“AddTableRow”,因为它不期望正确的类型。但我写这个,有点长但有效:

dep_pos_imbalance_detail.TableDataTable dt = ((dep_pos_imbalance_detail.TableDataTable)grid1.DataSet.Tables["Table"]);
dep_pos_imbalance_detail.TableRow dr = dt.NewTableRow();
foreach (var item in query_final)
{
   dr = dt.NewTableRow();
   dr.name = item.name;
   if (item.deal_date.HasValue)
       dr.deal_date = item.deal_date.Value;
   else
       dr.Setdeal_dateNull();
   dt.AddTableRow(dr);
}