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;
}
}
在这一点上,我将感谢任何帮助,所以如果你正在查看这篇文章,并有一个想法,请让我知道,因为我已经花了一整天的时间在这上面。
你需要的是创建一个接口来描述你希望你的数据访问类做什么。
。从你的样本
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,是创建一个巨大的类,对两者都有必要的支持,并基于用户所选择的,使用相应的对象和类。此外,您还可以创建多个类,每个类对应一个数据源,然后创建一个着陆类,它将根据用户选择的内容重新路由到正确的数据源提供程序类。不是很漂亮,但可能会起作用…