gpt4 book ai didi

c# - 将同一对象附加到 Entity Framework 6 中的不同上下文

转载 作者:太空狗 更新时间:2023-10-29 22:59:10 26 4
gpt4 key购买 nike

从我读到的所有内容到现在,应该不可能将同一个对象附加到不同的 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 引入了代码优先风格以来,这是可能的,因为您只能使用 POCO 来做到这一点。

cachedUser 是一个普通的 C# 类。它没有关于它所附加的上下文的任何信息。此外,新的上下文实例对另一个上下文的更改跟踪器一无所知。因此无法检查 POCO 是否附加到任何地方的上下文。

cachedUser 不是 POCO,而是 proxy 对象时,这会发生变化。 (代理对象是 EF 动态创建的对象。它继承自实体类,它包含启用延迟加载和促进更改跟踪的代码和状态)。当您尝试将代理对象附加到第二个上下文时,您将得到一个异常:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

这就是为什么在许多情况下建议创建代理而不是 POCO。您可以使用 db.Users.Create() 代替 new User() 创建代理。

何时创建代理,这是否可能以及何时 EF 物化代理是超出此问题范围的主题。有关更多信息,请参见 here

关于c# - 将同一对象附加到 Entity Framework 6 中的不同上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22481572/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com