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

本文关键字:转换 问题 null 查询 DateTime LINQ | 更新日期: 2023-09-27 18:26:48

以下是我在linq查询中使用的数据表的配置:我有两个数据集文件(所有表的所有列都指定了DataType,并且它们的AllowDbNull属性设置为True):*deposit_position_inbalance.xsd:包含2个数据表:-不平衡-实时不平衡细节*dep_pos_imbalance_detail.xsd:包含1个数据表:-表

在下面的代码中,问题出现在"deal_date=b.deal_date"这两行。事实上,当我从数据库b.deal_date中检索到一个空值时,它在deposit_position_inbalance.Designer.cs中说:"用户代码未处理StrongTypeingException"表'ImbalanceDetailForRealTime'中列'deal_date'的值为DBNull。"指定的强制转换无效"。以下是它抛出错误的地方:

[global::System.Diagnostics.Degger NonUserCodeAttribute()]公共System.DateTime deal_date{得到{尝试{return((global::System.DateTime)(this[this.tableImbalanceDetailForRealTime.dell_dateColumn]);}catch(global::System.InvalidCastException e){throw new global::System.Data.StrungTypeingException("表'''ImplanceDetailForRealTime'''中列'''deal_date'''的值为DBNull。"+",e)//此处引发错误}}集合{this[this.tableImbalanceDetailForRealTime.deleteColumn]=值;}}
  • 我已尝试将行"deal_date=b.deal_date"替换为"deal_date=(DateTime?)b.deal_date"但我得到了两个编译错误:"dep_pos_imbalance_detail.TableDataTable.AddTableRow(string,System.DateTime)的最佳重载方法匹配有一些无效参数"answers"参数"2":无法从"System.DateTime?"转换为"System.DateTime'"
  • 我还尝试将"deal_date=b.deal_date"一行替换为"deal_date=b.deal_date==null?(DateTime)DBNull.值:b.deal_date"但我得到了一个编译错误:"无法将类型"System.DBNull"转换为System.DateTime'"
  • 然后,我尝试将行"deal_date=b.deal_date"替换为"deal_date=b.deal_date==null?(DateTime?)DBNull.值:b.deal_date"但我得到了一个编译错误:"无法将类型"System.DBNull"转换为System.DateTime?"
  • 我尝试了另一件事:将"deal_date=b.deal_date"替换为"deal_date=b.Isdeal_dateNull()?默认值(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"。我不希望将null以外的任何值作为默认值(我们是否必须放置默认值"以外的其他值才能使其工作?)UPDATE-->我尝试将null而不是,但设计器给出了以下错误:"该字符串未被识别为有效的DateTime。有一个未知单词从索引0开始。"

所以我不明白如何检索null值(我没有把它放在代码中,但我对类型double也有同样的问题)。我的印象是,我的列被设置为启用null值,但显然不是。。。此外,当我试图将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);
}

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

如果这是一个strongly typed DataSet,它会自动生成像Isdeal_dateNull这样的可为Null列的属性,您应该使用它。

if (!row.Isdeal_dateNull)
{
   //do something
}
  • 强类型数据集的高效编码
  • 检查DBNull会引发StrongTypeingException

我找到了解决问题的方法。在我的LINQ查询中,我将"deal_date=b.deal_date"替换为"deal_date=b.Field('deal_date')"。然后可以进行转换。然后我就不能使用设计器自动生成的方法"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);
}