1

からどのように継承しIDbConnectionますか? DatabaseType1 つのプロパティ ( MS Access、SQL サーバー、Paradox など)を追加したいと思います。私が言えることIDbConnectionはインターフェイスであり、したがって、インターフェイス継承チェーン全体のすべてのメンバーを実装することを望んでいると思います。それは大変な作業のようです。に 1 つのプロパティを追加する最良の方法は何IDbConnectionですか?

更新 私がやろうとしていることはこれです。頻繁に使用する 3 つのメソッドがあります。ExecuteReader、ExecuteNonQuery、ExecuteNonQueryGetIdentity です。これらは頻繁に使用され、パラメーター (IDbConnection Conn、文字列 SQLString、object[] SQLParams) があります。これら 3 つのメソッドとすべてのプロジェクト メソッドに DatabaseType を追加する最善の方法は、プロジェクトのコードを 1 行だけ更新する必要があるように、IDbConnection を「オーバーライド」することだと考えました。

パラメーターを追加して IDbCommand を作成する際に、私が異なる方法で行うことがいくつかあるため、DatabaseType を知りたいと思います。具体的には 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
}
4

2 に答える 2

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が、プロパティも利用できます。

于 2012-12-10T19:11:19.637 に答える
0

DbConnection は、インターフェイス IDbConnection を実装します。それを拡張することができます(すべてのインターフェースメソッドを実装する必要があります)

于 2012-12-10T18:51:32.053 に答える