【问题标题】:Dataset field DBNull -> int?数据集字段 DBNull -> int?
【发布时间】:2010-04-07 10:41:51
【问题描述】:

SQLServer int 字段。值有时为空。 DataAdapter 填充数据集 OK,可以在 DatagridView 中显示数据 OK。

当尝试以编程方式从数据集中检索数据时,Dataset 字段检索代码会引发 StronglyTypedException 错误。

 [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public int curr_reading {
        get {
            try {
                return ((int)(this[this.tableHistory.curr_readingColumn]));
            }
            catch (global::System.InvalidCastException e) {
                throw new global::System.Data.StrongTypingException("The value for column \'curr_reading\' in table \'History\' is DBNull.", e);
            }

通过在 get 访问器中检查 DBNull 并返回 null 来解决这个问题,但是...... 当数据集结构被修改(仍在开发中)时,我的更改(不出所料)消失了。

处理这种情况的最佳方法是什么? 看来我被困在数据集级别处理它。 是否有某种属性可以告诉自动代码生成器保留更改?

【问题讨论】:

    标签: dataset nullable dbnull


    【解决方案1】:

    在类型化数据集设计器中有nullvalue 属性。 默认情况下,它的值为throw exception(因此您生成的代码) 您可以将其设置为所需的default value.. 即。 0。 然后它将返回 0 而不是异常。 (生成其他代码)

    VS2008 :这直接在数据集设计器中工作。

    VS2005:它仅适用于设计器中的字符串,但您可以直接编辑 XSD 并设置属性 msprop:nullValue="0"

    【讨论】:

      【解决方案2】:
      1. 不要管自动生成的代码。无法“拦截”它的生成,因此您所做的任何更改迟早都会被吹走。

      2. .NET(至少是 .NET 2.0 system.data 位)不会从 DBNull 转换为其他任何内容。这很糟糕,但你无能为力。

      3. 编写一个名为 ToNullable() 或类似的扩展方法:它可以这样做:

      .

      public static Nullable<T> ToNullable(this object x){
          if(x == DBNull.Value)
             return default(T); // return null thing
          else
             return (T)x;
      }
      

      那你就可以了

      int? thing = DataRow["column"].ToNullable<int>();
      

      【讨论】:

      • 这确实有效。遗憾的是,我将通过使用带有字符串的索引器来放松我的强类型。
      • 意识到这是旧的,但只是想知道:你是如何让它工作的?我似乎无法让它作为扩展工作。我得到“找不到类型或命名空间名称'T'”。如果我将 添加到静态类,VS2010 会告诉我“扩展方法必须在非泛型静态类中定义”
      • 我明白了。我认为第一行应该是:public static Nullable&lt;T&gt; ToNullable&lt;T&gt;(this object x) where T : struct
      【解决方案3】:

      数据集将有一个布尔属性来指示空值。

      int curr_reading = ( Iscurr_readingColumnNull) ? 
                         <default_value> : row.curr_readingColumn;
      

      【讨论】:

      • 正确。没有扩展方法的经验,但相信它会失败,因为尝试使用 Dataset Get 访问器会触发错误。这个“内部”Datarow 测试有效。谢谢。鲍勃
      • 在父表中找到另一个字段,对于这个字段没有内部空测试。写了扩展方法。有效。谢谢大家。
      【解决方案4】:

      如果没记错,您需要将该行标记为正在编辑 - 使用 .BeginEdit() 或类似方法 - 然后进行编辑并保存该行,可能使用 .EndEdit() 或类似方法。您可能想稍微了解一下这些方法(它们可能在 DataSet、DataTable 或 DataRow 上)——我的记忆有点模糊。

      希望这至少会有所帮助。

      【讨论】:

        【解决方案5】:
        if(row["curr_reading"] is DBNull){
        
        }else{
            row.curr_reading;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-20
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          • 2016-11-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多