Привязать один и тот же объект к различным контекстам в Entity Framework 6

c# entity-framework-6 multithreading

Вопрос

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

Кто-нибудь знает, действительно ли это «новая функция» в EF6?

Некоторый код здесь. Вызов этого из нескольких разных потоков не дал никакого исключения, и если я изменил объект из другого потока перед сохранением, он принимает последние значения:

                        using (var db = new TestContext())
                        {
                            db.Users.Attach(_cachedUser);
                            MessageBox.Show("attached"); //I use this to pause the thread as long as I want
                            _cachedUser.UserCode = tbCode.Text;
                            _cachedUser.UserDesc = tbDesc.Text;
                            MessageBox.Show("ready to save"); //pause again
                            db.SaveChanges();
                        }

Изменить После получения ответа, почему это происходит, я также нашел, как проверить, является ли объект прокси-сервером или нет: http://msdn.microsoft.com/en-us/library/vstudio/ee835846(v=vs.100). ASPX

public static bool IsProxy(object type)
{
    return type != null && ObjectContext.GetObjectType(type.GetType()) != type.GetType();
}

Работает отлично.

Принятый ответ

Это было возможно, поскольку Entity Framework ввела стиль кода в первый раз, потому что вы можете сделать это только с помощью POCOs.

cachedUser - это простой класс C #. Он не имеет никакой информации о контексте, к которому он привязан. Кроме того, новый экземпляр контекста не имеет знаний о другом отслеживателе изменений контекста. Таким образом, нет возможности проверить, привязан ли POCO к контексту в любом месте.

Это изменяется, когда cachedUser не является POCO, а прокси- объектом. (Прокси-объект - это объект, создаваемый EF «на лету». Он наследует от класса сущности и содержит код и состояние, которое обеспечивает ленивую загрузку и облегчает отслеживание изменений). Когда вы пытаетесь подключить прокси-объект ко второму контексту, вы получите исключение:

Объект сущности не может ссылаться на несколько экземпляров IEntityChangeTracker.

Вот почему для многих сценариев рекомендуется создавать прокси вместо POCOs. Вы можете создавать прокси, используя db.Users.Create() вместо new User() .

Когда создавать прокси-серверы, возможно ли это вообще и когда материализованные прокси-серверы EF являются предметом, выходящим за рамки этого вопроса. Подробнее об этом можно узнать здесь .



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему