Как "наследовать" от IDbConnection - просто добавьте одно свойство (DatabaseType)
Как вы наследуете от IDbConnection
? Я хотел бы добавить одно свойство (DatabaseType
как MS Access, SQL-сервер, Paradox...). Из того, что я могу сказать IDbConnection
является интерфейсом, и поэтому я считаю, что они хотят, чтобы я реализовал все элементы во всей цепочке наследования интерфейса. Это похоже на большую работу. Каков наилучший способ добавить одно свойство в IDbConnection
?
Обновить То, что я пытаюсь сделать, это. У меня есть три метода, которые я интенсивно использую: ExecuteReader, ExecuteNonQuery, ExecuteNonQueryGetIdentity. Они интенсивно используются и имеют параметры (IDbConnection Conn, строка SQLString, object[] 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
}
2 ответа
Вы можете создать новый интерфейс MyDbConnection
с DatabaseType
собственность, но ни одна из существующих IDbConnection
реализации будут реализовывать ваш интерфейс.
Я думаю, что вам не важно, какая реализация IDbConnection
вы используете (MS Access, SQL-сервер, Paradox и т. д.). Вот почему у нас есть эта абстракция и DbProviderFactory
классы, которые являются абсолютно абстрактным типом базы данных, с которой мы работаем.
Кстати, вы всегда можете проверить тип 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. Вы можете просто расширить это (он должен реализовывать все методы интерфейсов)