Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以创建从强类型DataRow继承的自定义类吗?_C#_.net_Inheritance_Dataset - Fatal编程技术网

C# 我可以创建从强类型DataRow继承的自定义类吗?

C# 我可以创建从强类型DataRow继承的自定义类吗?,c#,.net,inheritance,dataset,C#,.net,Inheritance,Dataset,我正在从事一个庞大的、古老的项目,其中包含大量脆弱的代码,其中一些代码从.NET1.0时代就已经存在,其他人已经并将继续致力于此。。。所以我想尽量少改变 我的解决方案中有一个项目包含DataSet.xsd。此项目编译为单独的程序集(Data.dll)。数据库模式包括多个或多或少按层次排列的表,但这些表实际链接在一起的唯一方式是通过联接。例如,我可以从自动生成的代码中获取部门行和员工行对象EmployeeRow包含通过联接从员工对应的DepartmentRow中获取的信息 我正在制作一份新报告,以

我正在从事一个庞大的、古老的项目,其中包含大量脆弱的代码,其中一些代码从.NET1.0时代就已经存在,其他人已经并将继续致力于此。。。所以我想尽量少改变

我的解决方案中有一个项目包含DataSet.xsd。此项目编译为单独的程序集(Data.dll)。数据库模式包括多个或多或少按层次排列的表,但这些表实际链接在一起的唯一方式是通过联接。例如,我可以从自动生成的代码中获取
部门行
员工行
对象
EmployeeRow
包含通过联接从员工对应的
DepartmentRow
中获取的信息

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

Department1...Employee1...
Department1...Employee2...
Department2...Employee3...
但客户希望每个部门都呈现为标题,每个标题下都有员工列表。例如:

- Department1...
      Employee1...
      Employee2...
+ Department2...
我试图通过从自动生成的行对象继承层次对象来实现这一点。例如:

public class Department : DataSet.DepartmentRow {
    public List<Employee> Employees;
}
我得到一个
“Data.DataSet.DepartmentRow(System.Data.DataRowBuilder)”由于其保护级别而无法访问。
除第一个错误外,还有一个错误


有没有办法完成我想做的事情?或者还有什么我应该完全尝试的吗?

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

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类的概要说明。
/// 
公共类Class1:MyDataSet.MyTableRow
{
公共类1(DataRowBuilder rb):基本类(rb)
{
//
//TODO:在此处添加构造函数逻辑
//
}
}
}

我不确定装配布局是什么。如果您的新继承类型位于“Data.dll”之外,并且您需要访问内部构造函数。。。假设您仍然可以更改此程序集,您可以尝试添加“InternalsVisibleToAttribute”()。希望这有帮助

我最终找到了一个具有以下优点的解决方案:

  • 我不必向数据集合添加朋友;我只需要在我通常进行修改的部件中修改一个文件
  • 我不必更改自动生成的代码,这些代码在重新生成后将被覆盖
  • 在dataset的代码隐藏文件(dataset.cs,在VS2008中通过扩展dataset.xsd获得)中,我添加了一个新的分部类定义,该定义添加了一个具有不同签名但功能与现有内部构造函数相同的公共构造函数:

    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) { }
    }
    
    公共类部门:DataSet.DepartmentRow{
    公共部门(global::System.Data.DataRowBuilder DataRowBuilder rb):基本(rb,“放弃”){
    公开名单雇员;
    公共字符串[]某些经常使用的字段组{
    得到{
    返回新字符串[]{this.OneField,this.AnotherField};
    }
    }
    公共bool CanUserSeeDepartmentInformation(int UserID){}
    }
    

    不幸的是,在获得这个结果之后,我意识到它没有多大用处,因为
    DataSetTableAdapters.DepartmentTableAdapter
    中自动生成的代码仍然返回类型为
    DataSet.DepartmentRow
    的对象,我必须向下转换才能获得带有额外属性/方法的
    Department
    对象。这是不允许的,我也看不到一个简单的方法来绕过这个事实


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

    在构建项目时,我已经对此进行了测试。我仍然不会在我自己的代码中这样做,即使我理解您为什么要这样做。您是否在另一个程序集中的DataSet中尝试过?我在我的示例中尝试了这一点,并得到了“由于其保护级别而无法访问”错误。如果不修改原始代码中的访问器,则无法在其他程序集中执行此操作。理论上,可以通过创建运行时类型通过反射来执行此操作。我不推荐这样做,因为这很容易成为维护/调试的噩梦。如果你真的想跳进兔子洞,只需搜索“reflection create runtime type”(反射创建运行时类型)。这很难看,但你可以在不同的程序集中这样做,方法是将属性添加到强类型的
    DataRow
    类中,并指定新程序集可以看到它。
    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) { }
    }