1

你是怎么继承的IDbConnection?我想添加一个属性(DatabaseType例如 MS Access、SQL server、Paradox...)。据我所知IDbConnection是一个接口,因此我相信他们希望我实现整个接口继承链中的所有成员。这似乎是很多工作。添加一个属性的最佳方法是什么IDbConnection

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

我想知道 DatabaseType,因为在添加参数和构建 IDbCommand 时我会做一些不同的事情。专门用于日期时间。

例如:

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
}
4

2 回答 2

2

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

我认为您不应该关心IDbConnection您使用的是哪种实现(MS Access、SQL server、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,而且您的属性也将可用。

于 2012-12-10T19:11:19.637 回答
0

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

于 2012-12-10T18:51:32.053 回答