2012-04-09 4 views
3

Ich wollte Feedback zu Ihren Gedanken erhalten, ganze Objekte in einer Sitzung zu speichern. Zum Beispiel ein Kundenobjekt. Sobald ein Kunde sich in seinem Control Panel anmeldet, anstatt seine Daten jedes Mal, wenn er von einer ID, die in einer Sitzung gespeichert ist, erneut zu holen, was sind die Vor- und Nachteile des Speicherns des gesamten Kundenobjekts in einer Sitzung?Gedanken zum Speichern ganzer LINQ-Objekte in Sitzung?

So jederzeit erforderlich Sie den Kunden Objekt zu verweisen, könnten Sie einfach tun:

Customer c = (Customer)Session["objCustomer"]; 

Natürlich würden Sie brauchen, um eine Funktion zu überprüfen und haben, der die Sitzung aktualisiert wird. Sie müssen diese Funktion im Falle einer Nullsitzung oder nach einer Aktualisierung ausführen.

Abgesehen davon, gibt es irgendwelche anderen Probleme, die ich beachten sollte, es auf diese Weise zu tun? Es scheint, dass dies viel besser wäre, was das Programmieren angeht, und auch weniger Aufrufe an die Datenbank. Gedanken an jemanden?

+7

Sie müssen besonders vorsichtig sein, dass Sie nicht versuchen, lazy-loaded Eigenschaften des Objekts zu folgen. IMO, es ist besser, ein POCO-Objekt zu erstellen, das nur die Eigenschaften enthält, die Sie regelmäßig benötigen, und es in der Sitzung und nicht das gesamte LINQ-Objekt zu speichern. – mellamokb

+2

Einverstanden. Sie möchten ein benutzerdefiniertes Objekt zum Speichern Ihrer Statusinformationen in der Anwendung, getrennt von der eigentlichen Datenbank. Sie möchten nicht, dass Ausdrucksbäume und später bewertete Eigenschaften mit Ihrer Eigenmächtigkeit vermischt werden. – David

+0

Was mellamokb sagte. Hinzufügen, dass ich denke, dass es eine schlechte Idee wäre, weil jemand, der nach Ihnen kommt, versuchen könnte, etwas wie das Objekt zu aktualisieren und Fehler über den Kontext zu erhalten, der entsorgt wird. Die POCO-Methode verfügt über gut definierte und durchsuchbare Mechanismen, um Daten in einen Kontext zurück zu versetzen, sodass Sie in der Datenbank darauf reagieren können. So lange würde es in der App weniger stinken. – Felan

Antwort

7

Dies ist keine gute Idee.

Der Hauptgrund dafür ist, wie ORMappers funktioniert - sie mögen es nicht, wenn Sie Objekte aus verschiedenen Kontexten mischen. Und dies würde in dem von Ihnen vorgeschlagenen Szenario geschehen - Sie haben ein Objekt in der Sitzung, das durch einen anderen Kontext erstellt wurde, den Ihre nächsten (und folgenden) Anfragen verwenden. Sonner oder später würden Sie anfangen, Ausnahmen zu bekommen.

Persönlich bevorzuge ich einen Ansatz, bei dem ein einfaches Objekt mit der ID des Kunden (und wahrscheinlich anderen Attributen) in einer Sitzung (oder in den benutzerdefinierten Daten des Formulars Cookie) gespeichert wird und ich den Zugriff auf das Kundenobjekt umschlinge eine einfache Erklärung, die die Items Behälter beinhaltet:

(ein Produktionscode würde hier und da einige Kontrollen erfordert defensiver zu sein):

const string CUSTOMERITEM = "customeritem"; 
public Customer Current 
{ 
    get 
    { 
     if (HttpContext.Current.Items[CUSTOMERITEM] == null) 
     { 
      int id = retrieve_the_id; 

      using (DbContext ctx = GetCurrentDbContext()) 
      { 
       HttpContext.Current.Items.Add(CUSTOMERITEM, ctx.Customers.FirstOrDefault(c => c.ID == id); 
      } 
     } 
     return (Customer)HttpContext.Current.Items[CUSTOMERITEM]; 
    } 
} 

Artikel Behälter nur für die Zeit einer Anfrage dauert. Das obige Snippet stellt sicher, dass das Objekt nur einmal pro Anfrage geladen wird.

Natürlich kommt dies mit einem Preis von einer zusätzlichen Abfrage pro Anfrage im Vergleich zu Ihrem Ansatz. Aber der Vorteil ist, dass Sie niemals Datenbankkontexte durcheinander bringen.

Hinweis, dass es einige Geschäftsprozesse, die das Customer Objekt nicht benötigen, aber Sie können den Kunden-ID direkt und verwenden in Abfragen übergeben:

public IEnumerable<Order> CustomerOrders(int CustomerID) 
{ 
    // use the customer id directly, without first loading the customer object 
} 
2

Ich habe in der Frage von Wiktor in einem anderen beschrieben laufen Antworten. Ich verwende NHibernate, und wenn Sie Objekte in der Sitzung speichern, erhalten Sie Probleme beim Vergleichen, Probleme mit getrennten Sitzungen usw. Trotzdem gehe ich fort und speichere meine Objekte in der Sitzung. Ich stelle nur sicher, dass sie alle ihre eigenen Equals() - und GetHashCode() - Funktionen implementieren. Auf diese Weise kann ich Objekte aus verschiedenen Sitzungen vergleichen, um zu sehen, ob sie das gleiche Objekt sind. Ich mache es mir zur Gewohnheit, obj1.Equals(obj2) anstelle von obj1 == obj2 zu verwenden.

Natürlich gibt es immer Kompromisse - Sie gewinnen die Geschwindigkeit, die Abfrage nicht wiederholen zu müssen, im Gegensatz zu Komplexität in Ihrem Code. Welcher Weg für Sie richtig ist, hängt von den Besonderheiten Ihrer Situation ab.

0

mellamokb Ich bin damit einverstanden, dass Sie die Eigenschaften, die Sie benötigen, mitbringen. Sie können dies tun, indem Sie das Modell anpassen, und Sie können auch das Lazy Loading deaktivieren. Ansonsten denke ich, dass es ziemlich sicher ist.Wenn wir nicht alle diese Objekte als Referenzen speichern, dann gibt es kein Problem, wenn diese Objekte einmal in der Sitzung platziert werden. Das einzige Mal, dass Sie ein Problem verursachen können, ist, wenn beide Kontexte im Geltungsbereich sind.

Verwandte Themen