Entity Framework: Gibt es eine Möglichkeit zu überprüfen, ob der Kontext ein Objekt hat?
-
21-08-2019 - |
Frage
Situation:. Objekt in der Sitzung aus einem vergangenen Kontext kann nicht wie ein anderes Objekt der Eltern eingestellt werden, da ein anderes Objekt in einem neuen Kontext ist
Sagen, dass ich einen Benutzer in der Sitzung, die ich aus einem Kontext abgerufen hatte. Nun ist die Seite neu geladen hat, dass Zusammenhang entlassen worden, und ein neuer Kontext wird.
someUser = context.First(user => user.id == id);
Session["SomeUser"] = someUser
...
context.Dispose();
Seite neu laden
userAddress = new UserAddress();
userAddress.User = (User)Session["SomeUser"]; //BOOM NOT IN SAME CONTEXT
Was würde Ich mag zu tun ist:
if(!context.SomeUsers.Contains((User)Session["SomeUSer"]) //Only check context NOT DATABASE
{
//Reload from database
//Set user in session to new object
}
Die Idee ist, dass, wenn das Objekt in der Sitzung nicht zu dem aktuellen Kontext gehört, sie aus der Datenbank neu zu laden, so dass es nun „Besitz“ von demselben Kontext wie jedes anderen Objekt im aktuellen Kontext. (Ich verwende einen Kontext pro Anfrage)
UPDATE
Also habe ich diese vorübergehend, bis ich eine bessere Vorstellung davon bekommen, wie dieses Problem zu beheben:
Int32 sessionUser = sessionUser .UserID;
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
if (userCheck != sessionUser)
{
sessionUser = userCheck;
}
Die Idee ist, zu sehen, ob das Objekt in der Sitzung (sessionUser) die gleichen wie die „in“ Kontext ist. Nun ist die, wenn funktioniert gut. Zum ersten Mal der Kontext erstellt wird, die die Datenbank schlagen sollte und die Benutzer greifen. Einmal im Vergleich, ist es offensichtlich, dass sie nicht gleich sind und die sesionUser ist jetzt der Anwender im Kontext. Das nächste Mal, wenn geprüft wird, die sessionUser und die userToCheck gleich sind.
Problem ist immer noch die:
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
trifft immer die Datenbank. Dies ist keine gute Lösung.
Mehr aktualisieren
Meh kann dies die Antwort schließlich sein. Ich hatte diese Regel vergessen:
x eine Eigenschaft des Typs Object. Wenn Sie einen Object ausführen, es immer die Sicherungsspeicher getroffen. Das ist, was sie tun. Wenn Sie nicht wollen, eine Datenbankabfrage auszuführen, dann keine Object verwenden.
Lösung
Ok ich es.
ChatUser userCheck = (ChatUser)EntityContext.Context.GetObjectByKey(returnValue.EntityKey);
if(userCheck != returnValue)
{
sessionUser = userCheck;
}
Die GetObjectByKey Methode, die wie beschrieben wird:
GetObjectByKey versucht ein abrufen Objekt, das die festgelegte hat EntityKey von Object. Wenn das Objekt momentan nicht geladen in den Objektkontext, eine Abfrage in einem Versuch ausgeführt die Rückkehr Objekt aus der Datenquelle.
habe einige Tests und es tut, was es sagt. Das erste Mal durch (im Kontext auf Anfrage erstellt wurde) trifft es auf die Datenbank und überprüft, das gegen das Objekt, was in der Sitzung. Die beiden sind nicht die gleichen, so setzt er den sessionUser auf das neue Objekt, so dass nun die sessionUser im Zusammenhang mit und in der Sitzung. Die nächste Mal, um die GetObjectByKey Methode überprüft nur den Kontext (A Profiler keine Datenbank-Interaktion zeigte). Yay.
Andere Tipps
Warum nicht einfach überprüfen Sie die Benutzer-ID?
context.Users.Any(user => user.Id = ((User)session["SomeUser"]).Id)
Oder Sie können nur das Benutzerobjekt aus dem alten Kontext lösen und an den neuen Kontext mit Context.Attach attach ().