Entity Framework: Y at-il un moyen de vérifier si le contexte a un objet?
-
21-08-2019 - |
Question
Situation:. Objet en session d'un contexte passé ne peut pas être défini en tant que parent d'un autre objet depuis un autre objet est dans un nouveau contexte
Dire que j'ai un utilisateur en session que je l'avais récupéré d'un contexte. Maintenant, les rechargements de page, ce contexte a été rejeté, et un nouveau contexte est fait.
someUser = context.First(user => user.id == id);
Session["SomeUser"] = someUser
...
context.Dispose();
Recharger la page
userAddress = new UserAddress();
userAddress.User = (User)Session["SomeUser"]; //BOOM NOT IN SAME CONTEXT
Ce que je voudrais faire est:
if(!context.SomeUsers.Contains((User)Session["SomeUSer"]) //Only check context NOT DATABASE
{
//Reload from database
//Set user in session to new object
}
L'idée est que si l'objet en session ne fait pas partie du contexte actuel, rechargez de la base de données de sorte qu'il est maintenant « propriété » par le même contexte que tout autre objet dans le contexte actuel. (J'utilise un contexte par demande)
UPDATE
Je l'ai fait temporairement jusqu'à ce que je peux avoir une meilleure idée de la façon de résoudre ce problème:
Int32 sessionUser = sessionUser .UserID;
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
if (userCheck != sessionUser)
{
sessionUser = userCheck;
}
L'idée est de voir si l'objet en session (sessionUser) est le même que celui « dans » le contexte. Maintenant, le cas fonctionne très bien. La première fois que le contexte est créé, qui devrait frapper la base de données et de saisir l'utilisateur. Une fois par rapport, il est évident qu'ils ne sont pas les mêmes et le sesionUser est maintenant l'utilisateur dans le contexte. La prochaine fois que si est cochée, le sessionUser et userToCheck sont les mêmes.
Le problème est toujours le:
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
touche toujours la base de données. Ce n'est pas une bonne solution.
Plus Mise à jour
Meh cela peut être la réponse après tout. J'avais oublié cette règle:
x est une propriété de type ObjectQuery. Lorsque vous exécutez un ObjectQuery, il sera toujours frappé le magasin de support. C'est ce qu'ils font. Si vous ne voulez pas pour exécuter une requête de base de données, ne pas utiliser ObjectQuery.
La solution
Ok got it.
ChatUser userCheck = (ChatUser)EntityContext.Context.GetObjectByKey(returnValue.EntityKey);
if(userCheck != returnValue)
{
sessionUser = userCheck;
}
La méthode de GetObjectByKey qui est décrite comme suit:
GetObjectByKey tente de récupérer un objet qui a spécifié EntityKey du ObjectStateManager. Si l'objet est actuellement pas chargé dans le contexte de l'objet, une requête est exécuté pour tenter de retourner le objet à partir de la source de données.
Est-ce que des tests et il fait ce qu'il dit. La première fois (contexte a été créé sur demande), il frappe la base de données et vérifie objet contre ce qui est en session. Les deux ne sont pas les mêmes donc il donne le sessionUser au nouvel objet, ayant ainsi maintenant la sessionUser dans le contexte et en session. La prochaine fois, la méthode GetObjectByKey vérifie uniquement le contexte (Comme Profiler a montré aucune interaction de base de données). Yay.
Autres conseils
Pourquoi ne pas simplement vérifier l'ID utilisateur?
context.Users.Any(user => user.Id = ((User)session["SomeUser"]).Id)
Ou vous pourriez juste détacher l'objet utilisateur de l'ancien contexte et l'attacher au nouveau contexte en utilisant Context.Attach ().