2009-08-18 7 views
1

たとえば、FooとBarの2つのクラスがあります。このクラスはいくつかのテーブルにマップされます。NHibernateでデータアクセスメソッドを作成する最良の方法は何ですか?

今のところ、私はクラスごとに静的メソッドを追加、更新、削除、取得しています。

E.g.: 

public class Foo 
{ 
    private Guid _id; 
    private string _someProperty; 

    static Foo Get(Guid id); 
    static void Add(Foo foo); 
    static void Update(Foo foo); 
    static void Delete(Foo foo); 
} 

だから、私は私の物でなめらかに行う必要があるとき、私はそうのようにそれを言う:

Foo foo = Foo.Get(id); 

Foo newfoo = new Foo(); 
Foo.Add(newfoo); 

Foo.Update(newfoo); 

Foo.Delete(newfoo); 

は、それは良いアプローチですか? そうでない場合は、データにアクセスするためにどのようなアプローチを使用しますか?

おかげ

+0

@kitsuneとリポジトリの使用に同意します。しかし、アクティブなレコードのアプローチが必要な場合は、データアクセスのためのフードの下でnhibernateを使用してCastle Active Recordを使用することができます。私はそれを数回使用しており、小規模なプロジェクトには非常に適しています。 – pythonandchips

答えて

8

は基本的にActive Recordパターンの実装です。多くの人々がそれを使用しており、それは完全に有効なアプローチです。しかし、あなたのアプリケーションが非常に複雑な場合、または懸念の分離に関するフェティッシュがある場合は、次のような有用な情報が得られます。

私はDDD(domain-driven design)アプローチを推奨します。 DDDは、というリポジトリパターンを使用します。 DDDは、アプリケーションとその懸念事項を「モデル/ドメイン」、「インフラストラクチャ」、および「サービス」という異なるレイヤーに分けます。

リポジトリは、インフラストラクチャ層内に属するパターンです。 CustomerまたはEmployer(またはMonsterおよびWeapon)などのビジネスオブジェクトは、モデルレイヤー内にあり、モデル化しようとする 'ドメイン'のコアを表し、ビジネスロジックも担当します。サービスレイヤーを使用して、複数のモデルにまたがるアクティビティーを単純化、調整することができます。

各ドメインモデル(たとえば、クラスFooとBar)には、データベースアクセスを処理するリポジトリがあります。これにより、データベース呼び出しとモデルの分離が行われます。

public interface IFooRepository 
{ 
    Foo Get(Guid guid); 
} 

public class FooRepository : IFooRepository 
{ 
    public Foo Get(Guid guid) 
    { 
     //... DB voodoo magic happening 
     return foo; 
    } 
} 

あなたのリポジトリのためのすべての時間をボイラーのコードを書くことにうんざりしている場合にも、一般的なIRepository<T>を作成することができます。

このアプローチは本当にうまくいくので、コントロールの依存性注入/反転についても調べるべきです。

このアプローチの利点は、IFooRepositoryから派生した新しいクラスを簡単に実装できることです。これにより、データベースインフラストラクチャの変更を素早く受け入れることができます。例えば、XMLファイルからデータを読み込むFooRepository、またはNHibernateを使ってPostgres DBから読み込むFooRepositoryを作成することができます。

DDDについては、this,thisおよびthis articleを読むこともできます。

+0

警告として、dddは「値オブジェクト」や「集約ルート」などの用語で、最初はかなり複雑になります。絶望しないでください。 – kitsune

+0

これは、関係をモデル化しようとすると特に当てはまります。 (例えば、EmployeeオブジェクトにはManagerへの参照があります。あなたがEmployerを保存するとどうなりますか?Managerを保存する必要がありますか?誰がそれを保存しますか?)最後の段落の最初の記事ジミーボガード、それを扱う。 – kitsune

+0

あなたの答えをありがとう。私はリポジトリパターンを使用して、それが私に適しているかどうかを確認しようとします。アクティブレコードパターンを使用しましたか?リポジトリパターンはコードをよりクリーンにしますか? –

1

それは常にあなたが書いているソフトウェアの種類によって異なります。

個人的には、エンティティ自身がデータアクセスを行う場合は気に入らないのですが、エンティティはフィールドとプロパティを管理するだけであり、それ以上の処理を行うべきではありません。

非常に大規模なエンタープライズソフトウェアでは、すべてのNHアクセスを別のアセンブリに入れています。 HQLやその他の特定のものはビジネスロジックに属しません。これにより単体テストも容易になります。読む価値のあるa similar architecture explained on CodeProjectがあります。

NHを使用するのが簡単で、同じコードを何度も繰り返し書く必要がないため、エンティティの挿入、削除、および更新を可能にする一般的な方法がいくつかあります。例えば:

void Store(object entity); 
void Delete(object entity); 
T Get<T>(object id); 
IList<T> GetAll<T>(); 
void Lock(object entity); 
例えば、特定のインターフェイスで

追加の具体的な方法、:何をやっている

IList<Product> GetProductsWithAttribute(string attributeName, string attributeValue); 
0

大規模なアプリケーションを作成する場合は、Kitsuneの言葉が最良の方法です。

これは小さなクラスのセットで、5未満であれば、大企業のアプリケーションにならない場合は、NHibernate query helper (shameless plug)か、CodesmithがNHibernate classesを生成する方法を見ることができます。

最初のリンクでは、ビジネスルールの検証を実行するだけでオブジェクトを保持することができます。たとえば、IsValidEmail()というメソッドがあります。 CodeSmithテンプレートがこれ以上進んでいるが、仕事

NHibernateManager<User> manager = new NHibernateManager<User>(); 
User name = manager.ReadFirst(); 

// All items filtered (using OR) 
IList<User> list = manager.OrList("@Name", "12345", "@Name", "54321"); 

// Paged 
list = manager.Page(1,10); 

:あなたはその後、C reate、R EAD、U pdate、D eleteタスク、例えばを実行するために、クエリマネージャを使用します同様の原則で彼らはNHibernateセッションにあなたを公開します。

あなたが行ったActiveRecordパターンも完全にうまく、ドメイン駆動の純粋主義者によってのみ侮辱されます。唯一の問題は、User、ContactなどのオブジェクトがNHibernateのクエリとセッションを担当することですが、逆にオブジェクトはうまく自己完結しています。

2つ(またはリポジトリパターンを含めると3つ)のうちどれを消費する方がよいでしょうか?そして、最終的にどれがあなたのプロジェクトにとって最速かつ最も適切なのですか?

+0

あなたが提案したNHibernateManagerは、リポジトリパターンとよく似ています。私は20以上のエンティティを持っているので、私はリポジトリパターンを使用しようと考えています(私のエンティティとテストプロジェクトを作成して、それが私のために良いかどうかを確認します)。 –

関連する問題