Структура сущности:Есть ли способ проверить, есть ли в контексте объект?

StackOverflow https://stackoverflow.com/questions/675625

Вопрос

Ситуация:Объект в сеансе из прошлого контекста не может быть установлен в качестве родительского другого объекта, поскольку другой объект находится в новом контексте.

Допустим, у меня есть Пользователь в сеансе, которого я извлек из контекста.Теперь страница перезагружается, этот контекст был удален, и создается новый контекст.

someUser = context.First(user => user.id == id);
Session["SomeUser"] = someUser
...
context.Dispose();

Перезагрузка страницы

userAddress = new UserAddress();
userAddress.User = (User)Session["SomeUser"]; //BOOM NOT IN SAME CONTEXT

То, что я хотел бы сделать, это:

if(!context.SomeUsers.Contains((User)Session["SomeUSer"]) //Only check context NOT DATABASE
{
   //Reload from database
   //Set user in session to new object
}

Идея заключается в том, что если объект в сеансе не принадлежит текущему контексту, перезагрузите его из базы данных, чтобы теперь он "принадлежал" тому же контексту, что и любой другой объект в текущем контексте.(Я использую контекст для каждого запроса)

Обновить

Поэтому я сделал это временно, пока не получу лучшее представление о том, как это исправить:

Int32 sessionUser = sessionUser .UserID;
var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);
if (userCheck != sessionUser)
{
   sessionUser = userCheck;
}

Идея состоит в том, чтобы посмотреть, совпадает ли объект в сеансе (sessionUser) с объектом "в" контексте.Теперь if работает просто отлично.При первом создании контекста он ДОЛЖЕН попасть в базу данных и захватить пользователя.После сравнения становится очевидно, что они не совпадают, и sesionUser теперь является пользователем в контексте.В следующий раз, когда будет проверен этот if, sessionUser и userToCheck будут одинаковыми.

Проблема по-прежнему заключается в :

var userCheck = EntityContext.Context.ChatUsers.First(item => item.UserID == returnValueID);

ВСЕГДА попадает в базу данных.Это не очень хорошее решение.

Дополнительные обновления

В конце концов, это может быть ответом.Я совсем забыл это правило:

x - это свойство типа ObjectQuery.Когда вы выполняете ObjectQuery, он всегда попадает в хранилище резервных копий.Это то, что они делают.Если вы не хотите выполнять запрос к базе данных, то не используйте ObjectQuery.

Это было полезно?

Решение

Ладно, понял.

ChatUser userCheck = (ChatUser)EntityContext.Context.GetObjectByKey(returnValue.EntityKey);

if(userCheck != returnValue)
{
   sessionUser = userCheck;
}

Метод GetObjectByKey , который описывается как:

GetObjectByKey пытается извлечь объект, у которого есть указанный EntityKey из ObjectStateManager.Если объект в данный момент не загружен в контекст объекта, выполняется запрос в попытке вернуть объект из источника данных.

Провел некоторое тестирование, и оно делает то, что написано.При первом прохождении (контекст был создан по запросу) он попадает в базу данных и проверяет этот объект на соответствие тому, что находится в сеансе.Это не одно и то же, поэтому он присваивает sessionUser новому объекту, таким образом, теперь sessionUser находится в контексте и в сеансе.В следующий раз метод GetObjectByKey проверяет только контекст (поскольку профилировщик не показал взаимодействия с базой данных).Ура.

Другие советы

Почему бы просто не проверить идентификатор пользователя?

context.Users.Any(user => user.Id = ((User)session["SomeUser"]).Id)

Или вы можете просто отсоединить пользовательский объект от старого контекста и присоединить его к новому контексту с помощью Context.Attach().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top