如何将数据访问层分成更小的类

Posted

技术标签:

【中文标题】如何将数据访问层分成更小的类【英文标题】:How to separate the Data Access Layer into smaller classes 【发布时间】:2018-03-05 05:32:44 【问题描述】:

我的 3 层应用程序存在设计问题。通常我的数据库层只有这样一个类:

public class DA

    string _connString = "";

    public DA()
    
         _connString = ConfigurationManager.ConnectionStrings["MyConnString"].ToString();

    
    public DA(string connString)
    
        _connString = connString;
    

    private SqlConnection GetConnection()
    
       ...
    

    public Employee GetEmployee(int idEmployee)
    
        ...
    
    public Whatever GetWhatever(int idWhatever)
    
        ...
    

    ...

但现在我有一个相当大的项目,我想将 DA 类分成更小的类,如 DA_Employee、DA_Whatever 等。

我想一次只实例化 DA 并像这样访问其他类:

DA db = new DA(connString);

db.Employee.GetEmployee(12);
db.Whatever.GetWhatever(89);
db.Whatever.UpdateWhatever(89, "newname");

我宁愿没有这样的东西:

DA db = new DA(connString);
DA_Employee dbEmployee = new DA_Employee(connString);
DA_Whatever dbWhataver = new DA_Whatever(connString);

我认为我可以在我的主构造函数中实例化我的所有类并拥有一些属性来访问它们?

如何向 GetConnection() 授予对所有类的访问权限?

任何帮助和参考表示赞赏。 谢谢!

【问题讨论】:

【参考方案1】:

是的,您将类设为 DA 的属性。

public interface IRepository<T>

    T GetById(int id);


public class EmployeeRepository : IRepository<Employee>

    private SqlConnection sqlConn;

    public EmployeeRepository(SqlConnection sqlconn)
    
        this.sqlConn = sqlConn;
    

    public Employee GetById(int id)
    
        return new Employee();
    

将 SqlConnection 作为构造函数依赖传递。

public class DA : IDisposable

    private SqlConnection sqlConn;
    private IRepository<Employee> employeeRepo;
    private IReposiotry<Whatever> whateverRepo;

    public DA(string connectionString)
    
        this.sqlConnection = GetSqlConnection(connectionString);
        this.employeeRepo = new EmployeeRepository(this.sqlConnection);
        this.whateverRepo = new WhateverRepository(this.sqlConnection);
    

    public IRepository<Employee> Employee  get  return employeeRepo;  
    public IRepository<Whatever> Whatever  get  return whateverRepo;  

及其用法

using (var db = new DA("connectionString"))

    db.Employee.GetById(1);
    db.Whatever.GetById(10);

【讨论】:

谢谢!您还给了我一个具有通用功能的基类的想法。 快速提问:有什么理由我应该为 employeeRepo 使用全局变量而不是像 public IRepository Employee get; 这样的直接属性。放; 我认为最好使用私有变量而不是“自动属性”(我认为它是这样调用的?)的一个原因是我只能在访问时实例化我的类。我猜它的性能更好。 如果您注入存储库实例而不是新建它们,就像在这个答案中一样,您可以伪造或模拟它们(用于测试)。如果你这样做了,那么 SqlConnection 也会被注入——这就引出了为什么你甚至需要 DA 的问题。也许您的 DA 类只会产生 SqlConnections,您可以根据需要将它们传递到您的存储库实例中。什么是更好的变得固执己见,取决于您的要求,也许在另一个 SE 网站上询问更好。

以上是关于如何将数据访问层分成更小的类的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Node.js 将套接字消息拆分成更小的块

将巨大的(95Mb)JSON 数组拆分成更小的块?

如何将结果集拆分为更小的子集?

将多维数据集无限细分为 8 个更小的多维数据集的存储范例的名称是啥?

将数组分成更小的连续部分,使 NEO 值最大

将组件拆分成更小的组件,同时保持 Angular 中父组件的 `ngModel` 和 `ngModelChange` 绑定