5

私はNHibernate(およびORMS)を初めて使用し、それが提示する無数のさまざまなオプションを把握しようとしています。参考までに、私は別のビジネス オブジェクトで Fluent NHibernate を使用しています。これらのビジネス オブジェクトは、純粋にデータ アクセスに DTO を使用します。私のアプリケーション アーキテクチャは、Windows と Web の「フロント エンド」の両方をサポートする必要があります。

非常に多くのオプションがあるように見えるので、私の悩みは一般的なアプローチの1つです。私の DTO は、以下のサンプルのようになります。各 DTO には、BO から渡される ISession への参照があります。それらは、独自のロードと保存を担当します。

public class EmployeeDTO...

    // Data Properties to be persisted to the database
    public virtual int Id { get; private set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual ISession Session { get; set; }

    // Save logic
    public virtual void Save()
    {
        var transaction = Session.BeginTransaction();
        Session.SaveOrUpdate(this);
        transaction.Commit();
    }

    // Load logic
    public virtual void Load(int id)...

まず第一に: これは正しいアプローチですか?

第二 に、保存/読み込みコードがどこにあるかに関係なく、存続期間またはオブジェクトに同じ ISession を使用する必要がありますか、それとも ISessionFactory への参照を持ち、データベースとのやり取りが必要になるたびに新しいセッションを開く必要がありますか?

    // Open a new session every time I interact with the repository
    var session = FluentSupport.SessionFactory.OpenSession();
    var transaction = Session.BeginTransaction();
    Session.SaveOrUpdate(this);
    transaction.Commit();
    session.Close();
    // Close the session when I'm done

もちろん、常にオプション 3 があり、上記のどれもありません :)

4

4 に答える 4

10

一般に、DTO には動作 (保存、読み込みなど) は含まれておらず、それらが永続化される方法 (ISession) に関する情報も含まれていません。あなたが実際に作成しているのはデータ層のようです。ビジネス層も ISession を認識しないことが理想的です。とは言っても、必要に応じてこのレイヤー化をショートカットできますが、ORM がすべてのレイヤーを通過すると、後で別の ORM に変更するのが難しくなる可能性があります。

ISession の有効期間を管理するには、UnitOfWork パターンを使用するかどうかを決定する必要があります。これは基本的に、すべてのユーザー リクエストが新しい ISession を取得することを意味します。ISession の有効期間には他にもオプションがあり、その点で制限されることはありません。多くの場合、Web アプリ、Windows アプリ、その他のアプリケーションの種類に関するベスト プラクティスが存在する可能性がありますが、どちらを作成しているかは指定していません。

于 2009-10-07T09:02:48.630 に答える
9

読み込み/保存コードを DTO から分離してください。DTO オブジェクトは、基になるデータの単なるビューです。

クエリを実行するときは、変換を使用して DTO を返します。このようなもの:

resultSet = session.CreateCriteria(typeof(MyDataObject))
    .Add(query criteria, etc.)
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>())
    .List<IMyDTOObject>()
于 2009-10-07T13:06:52.403 に答える
3

DTO は「データ転送オブジェクト」を意味します。つまり、システム内で値または値のコレクションを渡すために使用されるダム オブジェクトです。それらは自分自身を永続化する責任を負うべきではなく、ドメイン層のドメイン オブジェクトに 1-1 をマップすることさえすべきではありません。

于 2009-10-07T13:10:49.730 に答える
2

ISession の開閉は非常に安価です。あまりにも長い間開いたままにしておくことの問題は、接続プールがタイムアウトするまで接続を再利用できないことです。これは、マルチユーザー アプリケーションで問題になる可能性があります。

あなたのシナリオでは、おそらくサービス指向のアプローチを使用して、取得データを保存します。つまり、DTO はサービス境界内で内部的にのみ使用されます。同じように見えるオブジェクトをコピーする必要がある場合は、この特定の目的のために作成されたAutoMapperを参照することをお勧めします。Windows のみまたは Web のみのプロジェクトの場合は問題ありません。混ぜる時です。Windows アプリでは、Web アプリと同じ方法でセッションを処理することはできません。

于 2009-10-07T12:42:55.237 に答える