28 Stimmen

NHibernate-Sitzungsverwaltung in ASP.NET MVC

Ich spiele gerade mit der Klasse HybridSessionBuilder aus dem Blogbeitrag von Jeffrey Palermo herum:

http://jeffreypalermo.com/blog/use-this-nhibernate-wrapper-to-keep-your-repository-classes-simple/

Mit dieser Klasse sieht mein Repository wie folgt aus:

public class UserRepository : IUserRepository
{
    private readonly ISessionBuilder _sessionBuilder;

    public UserRepository(ISessionBuilder sessionBuilder)
    {
        _sessionBuilder = sessionBuilder;
    }

    public User GetByID(string userID)
    {
        using (ISession session = _sessionBuilder.GetSession())
        {
            return session.Get<User>(userID);
        }
    }
}

Ist dies der beste Weg, um über die Verwaltung der NHibernate-Sitzung / Fabrik zu gehen? Ich habe etwas über Unit of Work und das Erstellen einer Sitzung pro Webanforderung und Flushing am Ende gehört. Soweit ich das beurteilen kann, tut meine derzeitige Implementierung nichts von alledem. Sie verlässt sich im Grunde auf das Repository, um die Sitzung aus der Sitzungsfabrik zu holen und sie zur Ausführung der Abfragen zu verwenden.

Gibt es bei dieser Art des Datenbankzugriffs irgendwelche Fallstricke?

1 Stimmen

Ich bin mir nicht sicher, ob es Fallstricke gibt, aber Sie können sich eine Implementierung des Unit-of-Work-Musters unter Verwendung von Rhino.Commons in Steve Bohlens www.autumnofagile.net...he ansehen: Building an MVC app with NHibernate, Windsor and Rhino.Commons... es ist eine tolle Serie

36voto

Jamie Ide Punkte 46985

Sie sollten Ihre ISession nicht in eine using-Anweisung verpacken - der Sinn der Übergabe des ISessionBuilders an den Repository-Konstruktor (Dependency Injection) besteht darin, dass der aufrufende Code für die Kontrolle des Lebenszyklus der ISession verantwortlich ist. Wenn Sie die ISession in eine using-Anweisung einschließen, wird Dispose() für die ISession aufgerufen, und Sie können die Objektmitglieder nicht verzögert laden oder sie persistieren.

Wir machen etwas Ähnliches, indem wir einfach eine ISession an den Repository-Konstruktor übergeben. Der Code von Herrn Palermo, so wie ich ihn verstehe, fügt einfach eine verzögerte Initialisierung der ISession hinzu. Ich glaube nicht, dass das nötig ist, denn warum sollte man ein Repository neu anlegen, wenn man es nicht benutzen wird?

10voto

JoshBerke Punkte 64214

Mit ASP.Net MVC möchten Sie sicherstellen, dass die Lebensdauer der Sitzung während der Action-Methode auf Ihrem Controller beibehalten wird, da nach dem Beenden Ihres Controllers alle Daten gesammelt werden sollten. Ich bin nicht sicher, ob dieser Mechanismus dabei helfen wird.

Vielleicht möchten Sie sich die S#arp Architechure ansehen, die eine Reihe von Bibliotheken und Anleitungen für den Aufbau von ASP.Net MVC-Anwendungen mit nHibernate ist. http://code.google.com/p/sharp-architecture/

0 Stimmen

Wir sind derzeit die Verwaltung dieser Sitzung Leben mit einem Beginn Anfrage und Ende Anfrage Aufruf in der global.asax (ignorieren css und js etc.) Wollte nicht haben, um jede Aktion mit einer Unit Of Work-Anweisung zu schmücken.

1 Stimmen

Ich war mit der End-Anfrage auf den ersten, aber dann, wenn ein kritischer Fehler auftreten würde die Anforderung bereits beendet die Seite wurde gerendert und ich sah nicht eine saubere Art und Weise, um den Fehler zu behandeln, andere als Senden der Benutzer auf eine generische Seite. Ich bevorzuge ein explizites Schließen der Sitzung (oder zumindest Commit der Transaktion), wie Sie vom Controller zur Ansicht bewegen.

3voto

Kevin Pang Punkte 40296

Dies ist der Aufbau, den ich nach weiteren Recherchen verwendet habe. Scheint gut zu funktionieren und hat nicht die lästige Angewohnheit, eine ISession auf statische Datei-Anforderungen wie die meisten Leitfäden da draußen zu erstellen:

http://www.kevinwilliampang.com/2010/04/06/setting-up-asp-net-mvc-with-fluent-nhibernate-and-structuremap/

0 Stimmen

Was genau ist der Grund dafür, dass die Sitzung für statische Dateianfragen geöffnet wird?

0 Stimmen

Die meisten Lösungen verwenden einen Request Handler, der, da IIS 7 alles in der integrierten Pipeline abwickelt, auch Anfragen an statische Ressourcen und nicht nur Seitenanfragen bearbeitet. Daher startet der Handler eine Nhibernate-Transaktion/Sitzung für jede Anforderung, auch für Anforderungen an statische Ressourcen.

1voto

Min Punkte 2985

Ich würde die Sitzungen nicht bei jeder Datenanforderung an NHibernate öffnen und schließen. Ich würde die Unit-of-Work-Bibliotheken verwenden, die viele andere vorschlagen, oder mich weiter einlesen. NHForge.org ist in den Startlöchern und ich glaube, dass es dort einige Praktiken zum Einrichten von NHibernate für eine allgemeine Webanwendung gibt.

Einer der "Oh, wow, das ist cool"-Momente, die ich mit NHibernate erlebt habe, war die Nutzung der Vorteile, die das faule Laden von Collections während der Entwicklung bietet. Es war eine tolle Erfahrung, dass ich nicht all diese Joins durchführen musste, um Daten zu einem zugehörigen Objekt anzuzeigen.

Wenn Sie die Sitzung auf diese Weise schließen, wäre das oben beschriebene Szenario nicht möglich.

Es könnte auch etwas mit den Transaktionen los sein.

1voto

Giorgio Bozio Punkte 2952

Ich habe gerade eine saubere Lösung gefunden, die Unity verwendet, um eine Sitzung pro Anfrage zu injizieren:

http://letsfollowtheyellowbrickroad.blogspot.com/2010/05/nhibernate-sessions-in-aspnet-mvc.html

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X