抽象数据库类/API的合适方法

本文关键字:方法 API 数据库 抽象 | 更新日期: 2023-09-27 18:09:11

由于一个策略,我必须使用MS Access,但因为它不支持实体框架,我决定创建我自己的类,抽象出MS Access特定的代码如下:

public class DB
{
    public string path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
    public string fileName = "db.mdb";
    public string connectionString;
    public OleDbConnection connection = null;
    public DB()
    {
        this.connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; " +
            "Data Source=" + this.path + "''" + this.fileName;
        connection = new OleDbConnection(connectionString);
        connection.Open();
    }

    public OleDbDataReader Read(String queryString)
    {
        OleDbCommand cmd = new OleDbCommand(queryString, connection);
        return cmd.ExecuteReader();
    }
    ~DB()
    {
        if (connection != null)
        {
            connection.Close();
        }
    }
}

我有几个问题:

  1. 这是一个很好的方法来抽象的数据库,所以我可以更容易地取代它以后或者有一个更合理的方式来做到这一点?
  2. 如何确保数据库连接在完成时始终关闭?
  3. 是否有问题,如果有DB的多个实例与开放的连接?即,你可以有多个连接到MS Access数据库(或者我应该在这里使用单例模式)?

抽象数据库类/API的合适方法

你的问题的边界是"太宽"导致堆栈溢出;考虑在实际可部署的情况下测试每个更改。也就是说,我可以提出一些一般性的建议:

如果你要"抽象"一个API,让它与你想要抽象的接口相匹配。例如,如果你的目标是实体框架,让你的类返回DbSet<YourClass>而不是赤裸裸的YourClass实例。这应该允许您切换到EF,而无需更改代码。

让你的DB类(可怕的名字;我建议YourBusinessModel)继承DbContext,实现Dispose,并使用如下代码:

using (var bm = new YourBusinessModel(yourDbConnection))
{
    bm.YourEntities.Load(predicate);
    foreach (var ye in bm.YourEntities)
        DoSomethingWith(ye.InterestingProperty);
}

不要使用终结器,除非你真的非常需要它们,而我认为你并不需要它们。

尝试建立多个连接到Access数据库是非常危险的,除非它们都是只读的。如果您有一个并行运行的写入器,我建议序列化对数据库的访问。如果这太难的话,让它成为单例可能是一个不错的第一个版本。