2009-10-07 4 views
5

Ich bin neu in NHibernate (und ORMS) und versuche, die unzähligen verschiedenen Optionen, die es bietet, in den Griff zu bekommen. Als Referenz verwende ich Fluent NHibernate mit separaten Geschäftsobjekten, die wiederum DTOs ausschließlich für den Datenzugriff verwenden. Meine Anwendungsarchitektur muss sowohl Windows- als auch Web-Frontends unterstützen.Der beste Ansatz für den Bau von NHibernate DTO's

Meine Quandry ist eine der allgemeinen Ansatz, da es so viele Möglichkeiten zu sein scheint. Mein DTO sieht ungefähr so ​​aus wie das folgende Beispiel. Jeder DTO hat einen Verweis auf eine ISession, die ihm vom BO übergeben wird. Sie sind verantwortlich für ihre eigene Last und sparen:

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)... 

Vorweg: Ist dies der richtige Ansatz zu nehmen - sollte die DTO die Fähigkeit hat, zu speichern und zu sich selbst zu laden?

Zweitens: Unabhängig davon, wo die Save/Load-Code liegt, sollten Sie die gleiche ISession für die Lebensdauer oder ein Objekt verwenden, oder sollte sie haben einen ref zum ISessionFactory und öffnen Sie eine neue Sitzung jedes Mal, Datenbank-Interaktion Wird benötigt?

// 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 

Natürlich gibt es immer die Option 3, keine der oben genannten :)

+0

Wenn ein Objekt weiß, wie sich selbst zu retten ist DAO genannt, das nichts mit DTO –

Antwort

10

Im Allgemeinen DTOs Verhalten nicht enthalten (wie Speichern, Laden) und enthalten keine Kenntnisse darüber, wie sie beharrte erhalten (ISession). Es klingt wie das, was Sie wirklich erstellen, ist eine Datenschicht. Ihre Business-Schicht sollte idealerweise auch nicht über ISession Bescheid wissen. Das heißt, Sie können diese Ebenenbildung beliebig abkürzen, wie es Ihren Anforderungen entspricht, aber es wird wahrscheinlich schwierig sein, später zu einem anderen ORM zu wechseln, wenn Ihr ORM durch alle Ebenen blutet.

Für die Lebensdauerverwaltung von ISession müssen Sie entscheiden, ob Sie das UnitOfWork-Muster verwenden, das im Grunde besagt, dass jede Benutzeranforderung eine neue ISession erhält. Es gibt auch andere Optionen für die Lebensdauer von ISession, und Sie sind in dieser Hinsicht wirklich nicht eingeschränkt. Häufig gibt es Best Practices für Web-Apps und Windows-Apps im Vergleich zu anderen Anwendungstypen, aber Sie haben nicht angegeben, was Sie geschrieben haben.

+0

die architecure zu tun hat sowohl Web (Silverlight) und Fenster (WPF) – Steve

+0

ich die Frage, um diese abzudecken Klärung zu unterstützen. .. – Steve

2

Die ISession ist sehr günstig zu öffnen/schließen. Das Problem, sie zu lange offen zu halten, besteht darin, dass der Verbindungspool die Verbindung nicht wiederverwenden kann, bis das Zeitlimit überschritten wird oder was nicht. Dies könnte ein Problem in einer Mehrbenutzeranwendung sein.

In Ihrem Szenario würde ich wahrscheinlich für einen serviceorientierten Ansatz zum Speichern von Daten abrufen gehen. Das bedeutet, dass der DTO nur intern innerhalb der Dienstgrenzen verwendet wird. Wenn Sie Objekte kopieren müssen, die gleich aussehen, schlage ich vor, dass Sie sich die AutoMapper ansehen, die für diesen speziellen Zweck erstellt wurde. Wenn Sie nur ein Windows- oder nur Web-Projekt haben, ist das kein Problem. Es ist, wenn du mischt. Sie können die Sitzungen nicht in einer Windows-App wie in einer Webanwendung auf dieselbe Weise behandeln.

9

Halten Sie Ihren Lade-/Speichercode getrennt von Ihren DTOs. Die DTO-Objekte sind nur Ansichten der zugrunde liegenden Daten.

Wenn Sie Ihre Abfragen ausführen, geben Sie die DTOs mithilfe einer Umwandlung zurück. Etwas wie dieses:

resultSet = session.CreateCriteria(typeof(MyDataObject)) 
    .Add(query criteria, etc.) 
    .SetResultTransformer(Transformers.AliasToBean<MyDTOObject>()) 
    .List<IMyDTOObject>()
+0

Welche Kriterien kann ich in der Add-Methode verwenden (um die Domäneneigenschaft mit der DTO-Eigenschaft zu verknüpfen)? –

+0

@SilvioDelgado: Es tut mir leid, ich habe nicht mit NHibernate in über 3 Jahren gearbeitet, also weiß ich nicht. –

+0

Kein Problem. Trotzdem danke. :) –

3

DTO sind gemeint, um "Datenübertragungsgegenstände" zu sein. Dies sind dumme Objekte, die zum Übergeben von Werten oder Wertansammlungen in Ihrem System verwendet werden. Sie sollten nicht dafür verantwortlich sein, dass sie selbstständig bleiben oder sogar 1-1 zu Domänenobjekten in Ihrer Domänenebene zuordnen.