c#数据库包装器支持多个数据库

本文关键字:数据库 支持 包装 | 更新日期: 2023-09-27 18:12:50

我目前正在创建一个支持MySQL和MSSQL数据库的c#应用程序。我的问题是我的包装。我有我的代码为MySQL工作,但我有问题修改它以支持多个数据库。

如果你看一下我的代码的精简版本,你会看到我有一个DBMySQL类型的dbConn对象,如果我只想要MySQL支持,这是很好的。我需要修改DBMySQL成为通用的东西,这样我就可以运行dbConn = new DBMySQL(…)和dbConn = DBMSSQL(…),然后我可以简单地调用dbConn. somemethod()并让它在适当的数据库上工作。我希望尽可能保持相同的设置,因为我在DBMySQL和DBMSSQL类中有其他东西用于批量插入数据库和特定的错误检查。

我在想/试图声明像Object dbConn这样的东西,然后操纵它,但这并没有那么顺利。然后我尝试使用对象类型的枚举类,但我也有问题。我知道有许多第三方库可以完成所有这些工作,但我更愿意使用我自己的代码。

有没有人有任何建议我如何修改我的DBWrapper来解决这个问题?

//WRAPPER CLASS THAT CALLS DBMySQL, ISSUE IS I NOW NEED TO SUPPORT 
//DBMSSQL as well, not just DBMySQL
class DBWrapper
{
    DBMySQL dbConn;
    public DBWrapper(...,string type)
    {
        if(type.Equals("MySQL")
        {
            dbConn = new DBMySQL(...);
        }
        //NEED TO REWORK TO SUPPORT THIS BELOW!!
        else if(type.Equals("MSSQL")
        {
            //NEED TO MODIFY TO SUPPORT MSSQL
            //ISSUE IS DbConn is of type DBMySQL
            //SO I CANNOT GO
            // DbConn = new DBMSSQL(...);
            // any ideas?
        }   
    }
    public void setQuery(string myquery)
    {
            dbConn.setQuery(myquery);
    }
}
class DBMySQL
{
    public string dbinfo;
    string query;
    public DBMySQL(...)
    {
        dbinfo = ...;
    }
    public void setQuery(...)
    {
        query = myquery;
    }
}
//NEED TO RE-WORK WRAPPER TO SUPPORT THIS
class DBMSSQL
{
    public string dbinfo;
    string query;
    public DBMSSQL(...)
    {
        dbinfo = ...;
    }
    public void setQuery(...)
    {
        query = myquery;
    }
}

在这一点上,我将感谢任何帮助,所以如果你正在查看这篇文章,并有一个想法,请让我知道,因为我已经花了一整天的时间在这上面。

c#数据库包装器支持多个数据库

你需要的是创建一个接口来描述你希望你的数据访问类做什么。

。从你的样本

public interface IDBAccess
{
     void setQuery(...);
}
public class DBMySQL : IDBAccess
{
    public string dbinfo;
    string query;
    public DBMySQL(...)
    {
        dbinfo = ...;
    }
    public void setQuery(...)
    {
        query = myquery;
    }
}
public class DBMSSQL : IDBAccess
{
    public string dbinfo;
    string query;
    public DBMSSQL(...)
    {
        dbinfo = ...;
    }
    public void setQuery(...)
    {
        query = myquery;
    }
}

现在你可以这样做:

IDBAccess dbConn;
dbConn = new DBMySQL();
dbConn = new DBMSSQL();

考虑到你是新手,建议你看看NHibernate或Castle ActiveRecord和Castle Windsor可能没有用。

您不应该创建一个处理两个数据库的大类。您应该为包装器IDBWrapper创建一个公共接口,然后为每个数据库单独实现。

在此之后,您可以创建一些逻辑来为您选择正确的实现。您不希望每次需要包装器时都编写这样的内容:
IDBWrapper db = (useMySQL ? new MySqlDBWrapper(...) : new MsSqlDBWrapper(...));

有几个选项。您可以使用抽象工厂,但实际上任何抽象创建数据库包装器的方法都可以。

您想在c#中重新实现数据库层是否有特定的原因?你有没有研究过使用say;实体框架,NHibernate或任何其他。net ORM?这样可以很好地封装所有数据访问,而不必过多地担心实现细节。此外,它们还提供了其他优势,例如为您将表映射到类(即,它们根据表中的内容或其他方式填充您的类),缓存和各种其他功能。

或者,如果你想创建你自己的接口,那么你必须做的就是声明一个接口,让你所有的数据库连接从这个接口继承,并将连接实例存储在接口类型的属性中。即:

public interface IDatabaseConnection
{
    void setQuery(string myQuery);
}
public class DBWrapper
{
    private IDatabaseConnection Connection { get; set; } 
    public DBWrapper(string type)
    {
        if(type == "MySql")
            Connection = new DBMySQL();
        else if(type == "MsSql")
            Connection = new DBMSSQL();
    }
}
public class DBMySQL : IDatabaseConnection
{
    ...
}
public class DBMSSQL : IDatabaseConnection
{
    ...
}

在ADO。. NET中,所有的连接类都继承自System.Data.Common。DbConnection,所以你想要的实际上是内置在。net -你所要做的就是将连接存储在DbConnection而不是SqlConnection/MySqlConnection中,并使用System.Data.Common中的类而不是System.Data.Sql/MySql/中的类。

你这里的主要问题,在我看来,是没有真正的SQL标准-除了简单的选择和插入,你将需要不同的语法SqlServer和MySql查询。为了解决这个问题,你需要使用Linq To SQL——如果你不想依赖库,这是一项大量的工作——或者,如果你只想让你的包装器执行特定的操作——你可以为每个数据库提供一个字典,存储这些操作的ready-for- String.Format查询模板,并在运行时应用于执行这些操作的包装器方法。

您还可以查看这些db上的通用存储库模式和ORM。

我能想到的一个快速hack,是创建一个巨大的类,对两者都有必要的支持,并基于用户所选择的,使用相应的对象和类。此外,您还可以创建多个类,每个类对应一个数据源,然后创建一个着陆类,它将根据用户选择的内容重新路由到正确的数据源提供程序类。不是很漂亮,但可能会起作用…