假设我正在设计一个可以处理任何数据库技术的类来创建连接,执行命令和检索数据等。
如果我需要为现有的RDBMS(如SQL Server,Oracle,FireBird等)创建一个通用的数据库处理类,我应该使用.net abstract-class / Interface {DbConnection,DbCommand,DbParameter,... }或{IDbConnection,IDbCommand,IDbParameter,...}?
我应该使用像
这样的代码吗?public bool CreateConnection(DatabaseTypeEnum type)
{
DbConnection conn ;
if(type==DatabaseTye.Oracle)
{
//....
}
}
public DbDataReader GetData()
{
DbCommand comm;
//...
}
,或者
public bool CreateConnection(DatabaseTypeEnum type)
{
IDbConnection conn ;
if(type==DatabaseTye.Oracle)
{
//....
}
}
public IDbDataReader GetData()
{
IDbCommand comm;
//...
}
而且,为什么?
答案 0 :(得分:5)
嗯......完全不同的问题:)
好的,不...
当你这样做时,你会违反开放式关闭原则......那个特定地方的switch / if语句让我感到不舒服:)。
我将实际创建保留给Factory类,您的代码不应该关心它是否与SQL Server,DB2或Oracle或其他任何内容通信。
理想情况下,您的代码应该只与IDbConnection,IDbCommand等或抽象基类(DbConnection,DbCommand等)通信。有时我确实发现你需要向特定的提供者转发(比如使用特定方法的SqlDataReader),但这种情况很少见。
Factory会将此switch / if语句封装到一个位置,以便于维护。您可以在app.config中进一步抽象实际创建。因此,在app.config中,您可以选择支持哪种类型的数据库后端,工厂将从那里获取并为您创建必要的数据库内容。
请参阅:this。阅读有关创建DbProviderFactory和连接部件的信息......
答案 1 :(得分:0)
为什么不使用泛型?
您可以像这样定义您的类:
public class DBHelper<T, Y, W> where T: DbConnection, new() where Y : DbCommand, new()
{
private T conn_ = new T();
private Y comm_ = new Y();
}
这就是我所做的,而且它很容易维护。
答案 2 :(得分:0)
您应该使用IDbConnection
和IDbCommand
,因为不同的数据库供应商将有不同的接口实现(对于他们的ADO.NET事物),但更好不完全如此你发布了。您应该将整个类设为通用类,以支持通用IDbConnection
和IDbCommand
。可能是这样的:
public class Db<T> where T : IDbConnection, new()
{
public bool CreateConnection()
{
T conn;
//now you dont need these lines since you dont have to worry about
//what type of db you are using here, since they all implement
//IDbConnection, and in your case its just T.
//if(type==DatabaseTye.Oracle)
//{
//....
//}
}
public DbDataReader GetData()
{
//get comm object from S conn
using(var conn = new S())
using (var comm = conn.CreateCommand())
//...
}
好处是您可以将要用于DbConnection
和DbCommand
的类型传递给此类,这对于MySQL .net连接器和Oracle连接器将是不同的。所以你从课外得到某种控制。您可以查看此question and my answer以获取基本实现的参考。