繁体   English   中英

将相同的对象附加到Entity Framework 6中的不同上下文

[英]Attach same object to different contexts in Entity Framework 6

从我读到的所有内容到现在,不应该将相同的对象附加到不同的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();
}

工作得很好。

这是可能的,因为实体框架引入了代码优先的样式,因为您只能使用POCO执行此操作。

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

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

IEntityChangeTracker的多个实例不能引用实体对象。

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

什么时候创建代理,这是否可行以及何时EF物化代理是一个超出此问题范围的主题。 有关这方面的更多信息,请点击此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM