Я очень новичок в структуре сущностей, так что, пожалуйста, терпите меня ...
Как я могу связать два объекта из разных контекстов вместе?
В приведенном ниже примере возникает следующее исключение:
System.InvalidOperationException: The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
void MyFunction()
{
using (TCPSEntities model = new TCPSEntities())
{
EmployeeRoles er = model.EmployeeRoles.First(p=>p.EmployeeId == 123);
er.Roles = GetDefaultRole();
model.SaveChanges();
}
}
private static Roles GetDefaultRole()
{
Roles r = null;
using (TCPSEntities model = new TCPSEntities())
{
r = model.Roles.First(p => p.RoleId == 1);
}
return r;
}
Использование одного контекста не вариант, потому что мы используем EF в приложении ASP.NET.





Вам нужно будет использовать тот же контекст (вы можете передать контекст методу getdefaultrole) или переосмыслить отношения и расширить сущность.
Обновлено: Хотел добавить, что это было для предоставленного примера, использование asp.net потребует от вас полностью продумать свой контекст и дизайн отношений.
Вы можете просто передать контекст .. IE:
void MyFunction()
{
using (TCPSEntities model = new TCPSEntities())
{
EmployeeRoles er = model.EmployeeRoles.First(p=>p.EmployeeId == 123);
er.Roles = GetDefaultRole(model);
model.SaveChanges();
}
}
private static Roles GetDefaultRole(TCPSEntities model)
{
Roles r = null;
r = model.Roles.First(p => p.RoleId == 1);
return r;
}
Да - работа в 2 или более контекстах не поддерживается в Entity Framework V1.
На всякий случай, если вы еще не нашли его, есть хороший FAQ по EF на http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx
Старый пост, но хорошая справочная ссылка ... теперь он поддерживается на ef-faq.org.
Сделайте это social.technet.microsoft.com/wiki/contents/articles/… сейчас.
Насколько я понимаю, вы хотите создавать экземпляры своей модели (с помощью бита «new XXXXEntities ()») как можно реже. Согласно MS (http://msdn.microsoft.com/en-us/library/cc853327.aspx), это довольно существенное снижение производительности. Так что заключать его в структуру using () - не лучшая идея. В своих проектах я получил доступ к нему с помощью статического метода, который всегда предоставляет один и тот же экземпляр контекста:
private static PledgeManagerEntities pledgesEntities;
public static PledgeManagerEntities PledgeManagerEntities
{
get
{
if (pledgesEntities == null)
{
pledgesEntities = new PledgeManagerEntities();
}
return pledgesEntities;
}
set { pledgesEntities = value; }
}
А затем я получаю его так:
private PledgeManagerEntities entities = Data.PledgeManagerEntities;
Это называется паттерном синглтона.
Пара вещей: (1) Я думал, что вам нужно быть осторожным, делая это, потому что контекст будет отслеживать любые загруженные им объекты, что приводит к увеличению размера экземпляра. (2) В статье, на которую вы ссылаетесь, также говорится: «В большинстве случаев вам следует создать экземпляр ObjectContext внутри оператора using». (3) Если один вызов SaveChanges () терпит неудачу, то все последующие, скорее всего, завершатся ошибкой, если вы не отсоедините отказавшие объекты. Если у вас несколько абонентов, использующих один и тот же контекст, вы можете запутаться. (4) ObjectContext не является потокобезопасным
Это абсолютно небезопасно для веб-приложений, и прирост производительности незначителен. За исключением особых случаев, вы обычно должны использовать один контекст для каждой бизнес-операции. Обычно это означает использование одного контекста для каждой страницы / окна.
@Kurian - Что касается приложения ASP.NET, вы абсолютно правы. Когда я ответил на этот вопрос три года назад, я сомневаюсь, что прочитал его достаточно близко три года назад, чтобы понять это :-).
Другой подход, который вы могли бы использовать здесь, - отсоединить объекты от одного контекста, а затем прикрепить их к другому контексту. Это своего рода взлом, и он может не сработать в вашей ситуации, но это может быть вариантом.
public void GuestUserTest()
{
SlideLincEntities ctx1 = new SlideLincEntities();
GuestUser user = GuestUser.CreateGuestUser();
user.UserName = "Something";
ctx1.AddToUser(user);
ctx1.SaveChanges();
SlideLincEntities ctx2 = new SlideLincEntities();
ctx1.Detach(user);
user.UserName = "Something Else";
ctx2.Attach(user);
ctx2.SaveChanges();
}
Почему вы назвали свой тип контекста данных
TCPSEntitiesи почему вы назвали свой объект контекста данныхmodel? И вы можете подумать о том, чтобы не использоватьnew, а передать в функцию предварительно созданный контекст данных или фабрику контекста данных. Вы также можете подумать об использованииEnumerable.SingleOrDefaultвместоEnumerable.First.