【问题标题】:How to extend DataRow and DataTable in C# with additional properties and methods?如何使用附加属性和方法在 C# 中扩展 DataRow 和 DataTable?
【发布时间】:2011-03-07 07:06:49
【问题描述】:

我想创建一个自定义 DataRow,它具有 - 比如说 - 一个名为 IsCheapest 的属性。

public class RateDataRow : DataRow
{
    protected internal RateDataRow(DataRowBuilder builder) : base(builder)
    {
    }

    public bool IsCheapest { get; set ;}
}

我想要一个只包含 ***RateDataRow***s 的新 DataTable,以便 .NewDataRow() 将 RateDataRow 实例作为新行返回。

扩展 DataTable 的类的实现应该是什么?

谢谢,

【问题讨论】:

    标签: c# ado.net datatable extend datarow


    【解决方案1】:

    我知道这是一篇旧帖子,但我无法让上面的示例正常工作。我有一个类似的问题,所以很想找到一个解决方案。经过一番研究,我发现以下工作:

    class Program
    {
        static void Main(string[] args)
        {
            MyDataTable t1 = new MyDataTable();
    
            t1.Columns.Add(new DataColumn("Name", typeof(string)));
            t1.Columns.Add(new DataColumn("DateOfBirth", typeof(DateTime)));
    
            MyDataRow r1 = t1.NewRow() as MyDataRow;
            r1["Name"] = "Bob";
            r1["DateOfBirth"] = new DateTime(1970, 5, 12);
            t1.Rows.Add(r1);
        }
    }
    
    [Serializable]
    public class MyDataTable : DataTable
    {
        public MyDataTable()
            : base()
        {
        }
    
        public MyDataTable(string tableName)
            : base(tableName)
        {
        }
    
        public MyDataTable(string tableName, string tableNamespace)
            : base(tableName, tableNamespace)
        {
        }
    
        /// <summary>
        /// Needs using System.Runtime.Serialization;
        /// </summary>
        public MyDataTable(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    
        protected override Type GetRowType()
        {
            return typeof(MyDataRow);
        }
    
        protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
        {
            return new MyDataRow(builder);
        }
    }
    
    [Serializable]
    public class MyDataRow : DataRow
    {
        public bool MyPropertyThatIdicatesSomething { get; private set; }
    
        public MyDataRow()
            : base(null)
        {
        }
    
        public MyDataRow(DataRowBuilder builder)
            : base(builder)
        {
        }
    }
    

    【讨论】:

      【解决方案2】:

      DataTable 公开了一个 GetRowType 虚拟方法,在派生类中覆盖它。任何尝试添加错误类型的行都会引发异常:

      class Program
      {
          static void Main(string[] args)
          {
              MyDataTable t = new MyDataTable();
              t.Rows.Add(t.NewRow()); // <-- Exception here, wrong type (base doesn't count).
          }
      }
      
      public class MyDataTable : DataTable
      {
          public MyDataTable()
              : base()
          { }
      
          protected override Type GetRowType()
          {
              return typeof(MyDataRow);
          }
      }
      
      public class MyDataRow : DataRow
      {
          public MyDataRow()
              : base(null)
          { }
      }
      

      【讨论】:

      • 这是正确的方法,但需要第二个构造函数,至少在 .Net Core 3.1 中是这样(在 NewRow() 上失败)。检查 Gavin Sutherland 的答案。
      【解决方案3】:

      根据您的问题,不清楚您是否熟悉类型化数据集。它们基本上就是您所要求的。

      您可以使用内置向导创建基于 XSD 的类型化数据集(并且 XSD 是从 Db 模式中提取的)。在 WinForms 项目中,选择“添加数据源”并按照步骤操作。

      即使您不想使用该模型,您也可以从代码中借用属性、部分类等。

      明智的做法是使用该模型或保持非常接近它。

      【讨论】:

      • 抱歉,这不是问题的答案,我知道已经晚了,但这是人们在谷歌上找到的与该主题相关的第一个条目。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      相关资源
      最近更新 更多