【问题标题】:convertion issue with DateTime being null in a LINQ queryLINQ 查询中 DateTime 为空的转换问题
【发布时间】:2012-03-24 02:21:25
【问题描述】:

这是我在 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。” “指定的演员阵容无效”。 这是它引发错误的地方:

[全局::System.Diagnostics.DebuggerNonUserCodeAttribute()] 公共 System.DateTime deal_date { 得到 { 尝试 { return ((global::System.DateTime)(this[this.tableImbalanceDetailForRealTime.deal_dateColumn])); } 捕捉(全局::System.InvalidCastException e){ throw new global::System.Data.StrongTypingException("表 \'ImbalanceDetailForRealTime\' 中列 \'deal_date\' 的值为 DBNull。" + "", e);//此处抛出错误 } } 放 { 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()?默认(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 作为默认值之外的任何其他值(我们是否必须放置默认值“”以外的其他内容才能使其工作?) 更新--> 我尝试使用 null 而不是,设计者给出了这个错误:“字符串未被识别为有效的日期时间。从索引 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);
}

【问题讨论】:

  • 如果这是 strongly typed dataset,它会自动为您应该使用的 Isdeal_dateNull 等可空列生成属性。
  • 这是你的运行代码吗?第一个name = a.bo_source_name之后没有逗号
  • 确实,这是我正在运行的代码,我删除了很多列以获得更好的可见性。我更正了,谢谢。
  • 您调用的 AddTableRow(string, System.DateTime) 方法是什么?如果第二个参数需要 DateTime,那么您无法传入 null 或 DBNull.Value。
  • 这是Visual Studio的数据集设计器自动生成的方法。事实上,它需要一个“日期时间”而不是一个“日期时间?”。但就是这样,我不知道如何通过设计器在数据表的列中设置“日期时间?”的类型。当我们查看我附上的图片时,我们会看到我的专栏的整个定义。

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


【解决方案1】:

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

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

【讨论】:

  • 您好蒂姆,确实存在这种方法,但我不知道如何将它插入到我的 LINQ 查询中。而且我也不想在交易日期为空时特别做某事,然后我想在我的列中插入空值。任何想法?谢谢
  • Truying "deal_date = b.Isdeal_dateNull() ? default(DateTime?) : b.deal_date" 给出:“dep_pos_imbalance_detail.TableDataTable.AddTableRow(string, System.DateTime) 的最佳重载方法匹配”有一些无效的参数”和“参数‘2’:不能从‘System.DateTime’转换? to 'System.DateTime'" 此图显示了我的数据集中的 deal_date 列的定义:developpez.net/forums/attachments/p91000d1331057135/dotnet/…
  • 当我尝试修改 NullValu 属性以从“(Throw Exception)”到“(Empty)”或“(Null)”时,设计器给出了这个错误:“输入的值不是对当前数据类型有效。”
  • 我们可以在我之前评论中的图片中看到我似乎无法设置“System.DateTime?”但只有“System.DateTime”。而且我不想要除 null 作为默认值之外的任何其他值(我们是否必须放置默认值“”以外的其他内容才能使其工作?)更新-->我试图将 null 改为 并且设计者给出了这个错误:“字符串未被识别为有效的日期时间。从索引 0 开始有一个未知单词。”。
【解决方案2】:

我找到了解决问题的方法。在我的 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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    相关资源
    最近更新 更多