我可以创建一个继承自强类型DataRow的自定义类吗?

时间:2010-05-11 18:57:15

标签: c# .net inheritance dataset

我正在开发一个庞大的旧项目,其中包含许多脆弱的代码,其中一些代码自.NET 1.0时代开始就已存在,并且已经并将由其他人工作......所以我我想尽可能少地改变。

我的解决方案中有一个包含DataSet.xsd的项目。该项目编译为单独的程序集(Data.dll)。数据库模式包括或多或少按层次排列的几个表,但表实际链接在一起的唯一方法是通过连接。我可以得到,例如自动生成的代码中的DepartmentRowEmployeeRow个对象。 EmployeeRow包含来自员工对应的DepartmentRow通过加入的信息。

我正在制作一份新报告,以查看多个部门及其所有员工。如果我使用现有的数据访问方案,我将能够获得的是类似电子表格的输出,其中每个员工在一行上表示,部门信息在其相应的列中反复重复。 E.g:

Department1...Employee1...
Department1...Employee2...
Department2...Employee3...

但客户想要的是让每个部门都像标题一样呈现,每个部门下面都有员工列表。 E.g:

- Department1...
      Employee1...
      Employee2...
+ Department2...

我正在尝试通过从自动生成的Row对象继承层次结构对象来实现此目的。 E.g:

public class Department : DataSet.DepartmentRow {
    public List<Employee> Employees;
}

通过使用Department对象的集合作为DataSource,我可以将数据嵌套在报表中,每个对象都将其Employees列表放在子报表中。

问题是这给了我The type Data.DataSet.DepartmentRow has no constructors defined错误。当我尝试构建一个构造函数时,例如

public class Department : DataSet.DepartmentRow {
    private Department() { }
    public List<Employee> Employees;
}

除第一个错误外,我收到'Data.DataSet.DepartmentRow(System.Data.DataRowBuilder)' is inaccessible due to its protection level.错误。

有没有办法完成我想要做的事情?或者还有其他我应该完全尝试的东西吗?

3 个答案:

答案 0 :(得分:4)

我能够在快速测试中继承数据行。请注意,这与数据行类位于同一程序集中。数据行类的构造函数标记为“内部”。

using System;
using System.Data;

namespace Blah
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    public class Class1 : MyDataSet.MyTableRow
    {
        public Class1(DataRowBuilder rb) : base(rb)
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }
}

答案 1 :(得分:2)

我不确定装配布局是什么。如果新的继承类型驻留在“Data.dll”之外,并且您需要访问内部构造函数...假设您仍然可以更改此程序集,则可以尝试添加“InternalsVisibleToAttribute”(http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx)。希望这可以帮助。

答案 2 :(得分:1)

我最终找到了一个具有以下好处的解决方法:

  1. 我不必将朋友添加到数据集;我只需要修改我通常进行修改的程序集部分中的一个文件。
  2. 我不必更改自动生成的代码,一旦重新生成就会被覆盖
  3. 在数据集的代码隐藏文件(DataSet.cs,通过扩展DataSet.xsd在VS2008中访问)中,我添加了一个新的部分类定义,它添加了一个具有不同签名的公共构造函数,但在功能上与现有的内部构造函数:

    public partial class DataSet {
        public partial class DepartmentRow {
            public DepartmentRow(global::System.Data.DataRowBuilder rb, string discard) : this(rb) { }
        }
        public partial class EmployeeRow {
            public EmployeeRow(global::System.Data.DataRowBuilder rb, string discard) : this(rb) { }
        }
    }
    

    然后,我可以在派生类中使用此构造函数:

    public class Department : DataSet.DepartmentRow {
        public Department(global::System.Data.DataRowBuilder DataRowBuilder rb) : base(rb, "discard") { }
    
        public List<Employee> Employees;
    
        public string[] SomeFrequentlyUsedGroupOfFields {
            get {
                return new string[] { this.OneField, this.AnotherField };
            }
        }
    
        public bool CanUserSeeDepartmentInformation(int UserID) { }
    }
    

    瞧!

    不幸的是,在实现这个结果之后,我意识到它并没有多大用处,因为DataSetTableAdapters.DepartmentTableAdapter中自动生成的代码仍然返回DataSet.DepartmentRow类型的对象,我不得不向下转换来获取我的具有额外属性/方法的Department对象。这是不允许的,我无法轻易解决这个问题。

    我可以将所有新成员移动到部分类代码隐藏,但我不确定哪些架构规范会违反。 (似乎有一些任意应用数据逻辑和业务逻辑之间的区别。)

相关问题