如何从 IDbConnection 'inherit' - 只需添加一个属性(数据库类型)



如何从IDbConnection继承?我想添加一个属性(DatabaseType,比如MS Access、SQL server、Paradox…)。根据我的判断,IDbConnection是一个接口,因此我相信他们希望我实现整个接口继承链中的所有成员。这看起来工作量很大。向IDbConnection添加一个属性的最佳方式是什么?

更新我要做的就是这样。我有三个常用的方法:ExecuteReader、ExecuteNonQuery和ExecuteNonQueryGetIdentity。它们被大量使用,并且具有参数(IDbConnection Conn、字符串SQLString、对象[]SQLParams)。我认为将DatabaseType添加到这三个方法以及我的所有项目方法的最佳方法是"覆盖"IDbConnection,这样我只需要更新项目中的一行代码。

我想知道DatabaseType,因为在添加参数和构建IDbCommand时,我会做一些不同的事情。具体针对DateTime。

例如:

public static System.Data.IDataReader ExecuteReader(System.Data.IDbConnection Conn, string SQL, object[] SQLParams)
// return IDataReader from connection, SQL string and Params. Params can be null. 
{
using (var cmd = Conn.CreateCommand())
{
cmd.CommandText = SQL;
AddParametersToCommand(cmd, SQLParams);   // add parameters to IDbCommand object if params not null
return cmd.ExecuteReader();  
}
}
private static readonly Regex regParameters = new Regex(@"@w+", RegexOptions.Compiled);
public static void AddParametersToCommand(IDbCommand Cmd, object[] Parameters)
/* Creates and ads unique parameters to an IDbCommand object to the CommandText SQL string.
* Tested types with SQL Update statement in MS Access/SQL Server: boolean, int, DateTime, text
* Parameter names in CommandText must start with the '@' char and can be any unique word (letter or number).
* E.g. calling code: cmd.CommandText = "Select * From SiteUser Where Site > @1 And User > @NewParam"
* 
* http://www.codeproject.com/Articles/15542/IDbDataParameter-error-in-NET  re: some DateTime issues
*/
{
if (Parameters != null && Parameters.Length > 0)
{
MatchCollection cmdParams = regParameters.Matches(Cmd.CommandText);
var paramNames = new List<String>();
foreach (var el in cmdParams)
{
if (!paramNames.Contains(el.ToString()))   // only add unique parameter names
paramNames.Add(el.ToString());
}
IDbDataParameter dp;
var dbType = GetDatabaseType(Cmd.Connection);
for (int n = 0; n < Parameters.Length; n++)
{
var param = Parameters[n];
dp = Cmd.CreateParameter();
dp.ParameterName = paramNames[n];
TypeCode myTypeCode = Type.GetTypeCode(param.GetType());
if (myTypeCode == TypeCode.DateTime)     // this workaround is needed for MS Access and SQL Server
{
if (dbType == DatabaseType.Access)
{
dp.DbType = DbType.DateTime;         // set dates as DbType.DateTime for MS Access and Paradox
dp.Value = param.ToString();         // Convert.ToDateTime(param).ToString("yyyy-MM-dd hh:mm:ss"));         
//Note: MS access cannot store years before December 30, 1899. They will be stored for some other year.
// for example. Jan 1 0001 will be stored as 2001.
}
else if (dbType == DatabaseType.MSSql)
{
dp.DbType = DbType.DateTime2;        // set dates as DbType.DateTime2 for SQL Server
dp.Value = param.ToString();
}
}
else
dp.Value = param;
Cmd.Parameters.Add(dp);
} // for n
} // if
}

您可以创建具有DatabaseType属性的新接口MyDbConnection,但现有的IDbConnection实现都不会实现您的接口。

我认为您不应该关心您使用的是IDbConnection的哪个实现(MS Access、SQL server、Paradox等)。这就是为什么我们有这种抽象和DbProviderFactory类,它们完全抽象了我们正在使用的数据库类型。

BTW您可以随时检查IDbConnection实例的类型,以查看您正在使用的实现(如果确实需要)。您的另一个选择(如果您真的需要该属性)-在IDbConnection实例上创建装饰器:

public class MyDbConnection : IDbConnection
{
private IDbConnection _connection;
public MyDbConnection(IDbConnection connection)
{
_connection = connection;
}
// here goes your property
public string DatabaseType { get; set; }
public void Close()
{
_connection.Close();
}
public IDbTransaction BeginTransaction(IsolationLevel il)
{
return _connection.BeginTransaction(il);
}
// implement other IDbConnection members by delegating work to _connection
}

您可以在任何地方使用这个装饰器作为IDbConnection,但您的属性也将可用。

DbConnection实现了接口IDbConnection。你可以扩展它(它必须实现所有的接口方法)

最新更新