Как связать объекты из нескольких контекстов с помощью Entity Framework

Я очень новичок в структуре сущностей, так что, пожалуйста, терпите меня ...

Как я могу связать два объекта из разных контекстов вместе?

В приведенном ниже примере возникает следующее исключение:

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.

Почему вы назвали свой тип контекста данных TCPSEntities и почему вы назвали свой объект контекста данных model? И вы можете подумать о том, чтобы не использовать new, а передать в функцию предварительно созданный контекст данных или фабрику контекста данных. Вы также можете подумать об использовании Enumerable.SingleOrDefault вместо Enumerable.First.

yfeldblum 03.05.2009 21:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
14
1
22 558
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вам нужно будет использовать тот же контекст (вы можете передать контекст методу 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.

Craig 23.02.2011 00:47

Сделайте это social.technet.microsoft.com/wiki/contents/articles/… сейчас.

Kit 12.11.2011 00:10

Насколько я понимаю, вы хотите создавать экземпляры своей модели (с помощью бита «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;

Это называется паттерном синглтона.

Mathias Lykkegaard Lorenzen 09.10.2011 00:52

Пара вещей: (1) Я думал, что вам нужно быть осторожным, делая это, потому что контекст будет отслеживать любые загруженные им объекты, что приводит к увеличению размера экземпляра. (2) В статье, на которую вы ссылаетесь, также говорится: «В большинстве случаев вам следует создать экземпляр ObjectContext внутри оператора using». (3) Если один вызов SaveChanges () терпит неудачу, то все последующие, скорее всего, завершатся ошибкой, если вы не отсоедините отказавшие объекты. Если у вас несколько абонентов, использующих один и тот же контекст, вы можете запутаться. (4) ObjectContext не является потокобезопасным

Tom Haigh 24.07.2012 15:03

Это абсолютно небезопасно для веб-приложений, и прирост производительности незначителен. За исключением особых случаев, вы обычно должны использовать один контекст для каждой бизнес-операции. Обычно это означает использование одного контекста для каждой страницы / окна.

Monstieur 01.08.2012 09:23

@Kurian - Что касается приложения ASP.NET, вы абсолютно правы. Когда я ответил на этот вопрос три года назад, я сомневаюсь, что прочитал его достаточно близко три года назад, чтобы понять это :-).

Ken Smith 01.08.2012 19:27

Другой подход, который вы могли бы использовать здесь, - отсоединить объекты от одного контекста, а затем прикрепить их к другому контексту. Это своего рода взлом, и он может не сработать в вашей ситуации, но это может быть вариантом.

    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();
    }

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