2

私は2つのクラスを持っています:

  • 従業員
  • 従業員の詳細

Employeeクラスには次のようなメソッドがあります。

public static Employee LoadEmployee(int id)
{
    StringBuilder selectQuery = new StringBuilder();

    string selectQuery = " my query with the parameter 'Id' ";
    dbGenerator _db = dbGenerator.Instance.Database;

    DbCommand selectCommand = _db.GetSqlStringCommand(selectQuery.ToString());
    _db.AddInParameter(selectCommand, "@id", System.Data.DbType.String, Id);

    //EXECUTE THE COMMAND
    using (IDataReader dr = _db.ExecuteReader(selectCommand))
    {
        if (dr.Read())
        {
            result = new Employee();
            Employee.LoadDataReader(result, dr);
        }

        dr.Close();
    }

    return result;
}

そして、クラスで同じことを行うメソッドがありEmployeeDetailsます...戻り値の型以外はまったく変更されません。

コードの行数を最小限に抑える方法があると確信しています。また、C#ジェネリックを使用すると読みやすくなり、ジェネリックは複数の実装のオーバーヘッドなしでタイプ セーフを提供します。

このようにクラスオブジェクトselectQueryを渡すことができるメソッドが必要ですParameterId

public static <T> LoadData<T>(Object object, string selectQuery, int paramId)
{
    // do stuff 

    // return <T>results;
}

任意の提案をいただければ幸いです。

4

5 に答える 5

1

ORM のみを使用するという他の提案は素晴らしいですが、このレイヤーをゼロから作成する正当な理由がある場合は、デザインを次のように修正できます。

public class Employee 
{
    public virtual void InitFromDataReader(DataReader dr) { }
}

public class EmployeeDetails : Employee
{
    public override void InitFromDataReader(DataReader dr) { }
}

public static TEmployee LoadEmployee<TEmployee>(int id) where TEmployee : Employee, new()
{
    using (DataReader dr = new DataReader()) 
    {
        var result = new TEmployee();
        result.InitFromDataReader(dr);
        return result;
    }
}

主な制約は、エンティティ オブジェクトに引数なしのコンストラクターが必要であるということです。そうしないと、LoadEmployeeメソッドはそれらを正しく作成できません。つまり、ファクトリ オブジェクトをパラメーターとしてメソッドに明示的に渡さない限り、.

于 2012-07-09T14:11:02.363 に答える
1

最善の方法は、ある種の ORM (EntityFramework または NHibernate) を使用することです。これは、一般的な管理を無料で利用できるためです。

ただし、次のようなものが機能する場合があります。

public static T LoadEntity<T>(int id, StringBuilder selectQuery) where T : Entity
        {
            dbGenerator _db = dbGenerator.Instance.Database;
            DbCommand selectCommand = _db.GetSqlStringCommand(selectQuery.ToString());
            _db.AddInParameter(selectCommand, "@id", System.Data.DbType.String, Id);
            //EXECUTE THE COMMAND
            using (IDataReader dr = _db.ExecuteReader(selectCommand))
            {
                if (dr.Read())
                {
                    T result = default(T);
                    EntityContext.LoadDataReader(result, dr);
                }
                dr.Close();
            }
            return result;
        }

ご覧のとおり、このソリューションでは、から継承し、メソッドEntityを含む必要があります。また、クエリを渡す必要があります。EntityLoadDataReader

免責事項: テストされていないコードです!

于 2012-07-09T14:03:43.523 に答える
1

同じインターフェイスから両方EmployeeEmployeeDetails 継承して、両方に LoadDataReader メソッドがあるようにします。

それから

public static T Load<T> (int id) 
    where T: IMyInterface

LoadDataReader メソッドで何らかのリフレクションや凝った処理を行う必要がある場合があります。

于 2012-07-09T14:03:44.397 に答える
1

EmployeeDataReaderまず、と の両方に共通の接地を用意しEmployeeDetailsDataReaderます。

ジェネリックは、ここで異なる戻り値の型を提供するのに役立ちます。したがって、それを処理するには基本クラス (またはインターフェイス) が必要です。例: EmployeeDataReaderBase<TEmployee>.

その後、データリーダーはこの基本クラスから継承できます。

次に、メソッドを次のように変更します。

public static Employee LoadEmployee<TEmployee>(int id, EmployeeDataReaderBase<TEmployee> datareader)
于 2012-07-09T14:04:33.903 に答える
1

インターフェイスメソッドとして「インターフェイス継承」を使用できますLoadDataReader(LoadDataReaderがEmployeeとEmployeeDetailsで異なると仮定します)。次に、インスタンスを静的な LoadEmployee メソッドに渡します。戻り値の型を void に設定します

interface IDataReader
{
   void Load(DataReader reader);
}

public class Employee : IDataReader
{
   // some code... members...

   public void Load(DataReader reader)
   {
        /// some code...
   }
}

public static void Load(IDataReader reader, int id)
{
   // lots of code...
   if (dr.Read())
   {        
        // the specific reader would create its own type within... 
        // there by keeping the instance creation with in the LoadDataReader.
        // ex: If reader's type is Employee it would create Employee and setup the object with info from the reader?
        reader.LoadDataReader(dr);

   }
}
于 2012-07-09T14:08:33.510 に答える