0

SQL リフティングのほとんどを行う大規模なプロジェクト用に、DAL_Baseという基本クラスがあります。

DAL_Baseには、SELECTステートメント、GetRecords()メソッド、およびvirtual FillData(IDataRecord).

public class DAL_Base<T> where T : IDisposable, new() {

  private string connStr;

  public DAL_Base() {
    connStr = ConfigurationManager.ConnectionStrings["CompanyDatabaseConnStr"].ConnectionString;
  }

  internal string SP_GET { get; set; }

  internal SqlConnection m_openConn {
    get {
      var obj = new SqlConnection(connStr);
      obj.Open();
      return obj;
    }
  }

  internal virtual T FillDataRecord(IDataRecord record) {
    return new T();
  }

  internal TList<T> Get() {
    if (String.IsNullOrEmpty(SP_GET)) {
      throw new NotSupportedException(string.Format("Get Procedure does not exist for {0}.", typeof(T)));
    }
    var list = new TList<T>();
    using (var cmd = new SqlCommand(SP_GET, m_openConn)) {
      cmd.CommandType = cmd.GetCommandTextType();
      using (var r = cmd.ExecuteReader()) {
        while (r.Read()) {
          list.Add(FillDataRecord(r));
        }
      }
      cmd.Connection.Close();
    }
    return list;
  }

}

他にもたくさんありますが、1 つの例としてはこれで十分です。

TListは単なるList<T>クラスです。

internal class TList<T> : List<T> {
  public TList() { }
}

私のクラスの 1 つがそれを継承するとき、基本クラスのFillDataRecord(IDataRecord).

たとえば、EmployeeDB ** は **DAL_BASE を継承します。

を呼び出すと、 DAL_BASEEmployeeDB.GetEmployeeList()を使用してレコードが取得されます。

public class EmployeeDB : DAL_Base<Employee> {

  private static EmployeeDB one;

  static EmployeeDB() {
    one = new EmployeeDB() {
      SP_GET = "getEmployeeList",
    };
  }

  private EmployeeDB() { }

  internal override Employee FillDataRecord(IDataRecord record) {
    var item = base.FillDataRecord(record);
    item.Emp_Login = record.Str("Emp_Login");
    item.Emp_Name = record.Str("Emp_Name");
    item.Emp_Email = record.Str("Emp_Email");
    item.Emp_Phone = record.Str("Emp_Phone");
    item.Emp_Role = record.Str("Emp_Role");
    return item;
  }

  public static EmployeeList GetEmployeeList() {
    var list = new EmployeeList();
    list.AddRange(one.Get());
    return list;
  }

}

上記のコードでは、 DAL_BaseメソッドをGetEmployeeList()呼び出すと、DAL_Base::FillDataRecord(IDataRecord)のみが呼び出されます。Get()

EmployeeDB::FillDataRecord(IDataRecord)を呼び出す必要がありますが、 DAL_Base::FillDataRecord(IDataRecord)を抽象化することはできません。

これを回避する方法は何ですか?

私が今知っているのは を作成するEventHandlerことだけです。これは私が今考えたものなので、それに向けて作業するつもりです。

もっといいルート知ってる人いたら教えてください!

4

1 に答える 1

1

1 つの解決策は、Derived.FillDataRecord のデリゲートをコンストラクターを介して基本クラスに渡すことです。

public class DAL_Base<T> where T : IDisposable, new() {

  private string connStr;

  public DAL_Base() {
    connStr = ConfigurationManager.ConnectionStrings["CompanyDatabaseConnStr"].ConnectionString;
  }
    private Func<IDataRecord, T> _fillFunc;

    public DAL_Base(Func<IDataRecord, T> fillFunc) : this() {
            _fillFunc = fillFunc;
    }

        // ... 
    internal TList<T> Get() {
    if (String.IsNullOrEmpty(SP_GET)) {
      throw new NotSupportedException(string.Format("Get Procedure does not exist for {0}.", typeof(T)));
    }
    var list = new TList<T>();
    using (var cmd = new SqlCommand(SP_GET, m_openConn)) {
      cmd.CommandType = cmd.GetCommandTextType();
      using (var r = cmd.ExecuteReader()) {
        while (r.Read()) {
          list.Add(_fullFunc(r));
}

そして派生クラスで:

public class EmployeeDB : DAL_Base<Employee> {
    public EmployeeDB() : base(r => FillDataRecord(r)) { }

  private Employee FillDataRecord(IDataRecord record) {
    var item = base.FillDataRecord(record);
    item.Emp_Login = record.Str("Emp_Login");
    item.Emp_Name = record.Str("Emp_Name");
    item.Emp_Email = record.Str("Emp_Email");
    item.Emp_Phone = record.Str("Emp_Phone");
    item.Emp_Role = record.Str("Emp_Role");
    return item;
  }
}
于 2013-10-16T22:43:34.793 に答える