2017-02-13 43 views
0

私は最近、私のニーズに合わせてDapperを調整する作業をしましたが、かなりうまくいきましたが、私は特定のコードが繰り返されていることに気づいたので、できるだけそれを小さくしたいと思っています。現在の動作は次のとおりです。継承クラスと汎用クラス

私は、保存、削除、取得などの基本操作を行う基本DALクラスを持っています。それに加えてIsNewという名前のプロパティがあります。推測すると、それが新しいエンティティか既存のエンティティかどうかが判断されます。

public class DalBase 
{ 
    public bool IsNew 
    { 
     get; 
     private set; 
    } 

    public static T New<T>() 
    { 
     // removed for clarity 
    } 

    public void Get<T>(params object[] parameters) 
    { 
     // removed for clarity 
    }  

    public void Save() 
    { 
     // removed for clarity 
    } 

    public void Delete() 
    { 
     // removed for clarity 
    } 
} 

私は私のエンティティを定義したい場合は、私はそれをこのようにするだろう、人を言うことができます:あなたは私のDALは、Entityクラスの内部に収容されている見ることができるように

public partial class Person 
{ 
    private PersonDal m_dal; 

    public bool IsNew 
    { 
     get 
     { 
      return m_dal.IsNew; 
     } 
    } 

    public int? PersonID 
    { 
     get 
     { 
      return m_dal.PersonID; 
     } 
    } 

    public string PersonName 
    { 
     get 
     { 
      return m_dal.PersonName; 
     } 
     set 
     { 
      m_dal.PersonName = value; 
     } 
    } 

    public string PersonSurname 
    { 
     get 
     { 
      return m_dal.PersonSurname; 
     } 
     set 
     { 
      m_dal.PersonSurname = value; 
     } 
    } 

    public DateTime? PersonDateOfBirth 
    { 
     get 
     { 
      return m_dal.PersonDateOfBirth; 
     } 
     set 
     { 
      m_dal.PersonDateOfBirth = value; 
     } 
    } 

    private Person() 
    { 
     m_dal = DalBase.New<PersonDal>(); 
    } 

    public static Person New() 
    { 
     return new Person(); 
    } 

    public static Person Get(int PersonID) 
    { 
     var personDal = DalBase.Get<PersonDal>(PersonID); 

     if (personDal == null) 
      return null; 

     var person = new Person(); 
     person.m_dal = personDal; 
     return person; 
    } 

    private class PersonDal : DalBase 
    { 
     public int? PersonID 
     { 
      get; 
      set; 
     } 

     public string PersonName 
     { 
      get; 
      set; 
     } 

     public string PersonSurname 
     { 
      get; 
      set; 
     } 

     public DateTime? PersonDateOfBirth 
     { 
      get; 
      set; 
     } 

     private PersonDal() 
     { 
      IsNew = true; 
     } 
    } 
} 

を。このようにして、マッピングや更新前の予備チェック、挿入などのあらゆる種類の処理を行うことができますが、ここにこのコードを貼り付けてコピーするのではありません。)エンティティの定義がすべて繰り返されるため、少し冗長であるように見えます。なぜなら、DateOfEdit、UserEditなどのすべてのテーブルに共通の列を追加することを考えているからです。それを1つの場所に追加して継承するのに便利です。各エンティティ定義に特定の列を保持するだけです。

public class EntityBase<T> where T : DalBase 
{ 
    protected T m_dal; 

    public bool IsNew 
    { 
     get 
     { 
      return m_dal.IsNew; 
     } 
    } 
} 

これは私が私の人のエンティティのような定義されていることができますので、私は特定のダルクラスで基本エンティティを継承できるようになる:

public partial class Person : EntityBase<PersonDal> 
私はこのようなジェネリックを使用している今でやってみました何

このアプローチの問題は、PersonDalがPersonエンティティのプライベートクラスであるため、エンティティ自身よりもアクセシビリティが低く、私はそれをpublicとして定義するだけです。DALは関係するエンティティそれ!

これを達成できる方法は他にありますか?

+1

私はあなたが過度に複雑なことをしていると思います...データレイヤプロジェクトを持ち、外部には必要のないものに 'internal'を使うのはどうですか? – grek40

+0

内部ファイルは同じファイルから引き続き使用できるので、ファイルは切り取られません。 DALは、エンティティクラス以外の場所からアクセスできないようにする必要があります。 – Rob

+0

しかし、あなたは 'DalBase.New ()'のエンティティクラスの外にそれを作成する予定です。また、誰が悪意のあるコーダが自分が望むところでも 'PersonDal'のコピーを作成することを阻止していますか?ネストされたクラスを使用すると、内部でアクセス可能な場合であっても、クラスをランダムに使用しないヒントが十分にあるはずです。この全体のアイデアにはかなり欠陥があります。 – grek40

答えて

1

DALはエンティティとは関係ありません。ここでコンセプトをミックスします。エンティティクラスのメンバフィールド/変数としてではなく、DALを個々のクラスとして使用し、エンティティタイプをDALに渡します。 エンティティでDALを使用する必要がある場合は、DIを使用してコンストラクタでDALインスタンスを渡します。

元のアプローチを使用する場合は、2つのエンティティタイプを持つ単純なEFプロジェクトを作成し、その動作を確認します。

+0

DALには、エンティティと関係があります。DALは、SINGLE行の挿入、更新、削除、またはフェッチに使用されるためです。このため、エンティティ自体を除いて他の誰も使用しないので、別のクラスとして使用することはできません。 – Rob

+0

DALはオブジェクトを知る必要はありません。DBに保持するだけです。継承はEFやnhibernateのように、ここで唯一使用可能な方法です。 http://www.springframework.net/doc-latest/reference/html/nh-quickstart.html すべてのインスタンスでプライベートdalエンティティを持つことは、少なくとも並行性の側面からは疑わしいです。 – Dexion

+0

DALはインスタンスを知っていなければならないと言っていますが、 1.実際にDALはDB内のテーブルを知っていて、インスタンスのプロパティをテーブルにマップする必要があります - リフレクションまたはトリックのようなEF/nhibernateの場合、重要ではない、速度を期待する。 2.パラメタ化されたSPを呼び出す場合、DALは、リフレクションでより少ないコピーSPパラメータ値を知り、結果エンティティもリフレクションでインスタンス化する必要があります。 – Dexion