我使用WPF,.NET 4.0和EF5。我想将打开的ObjectContexts保持在最小值,因此我使用了一个使用块中的每个对象上下文。
无论如何,当我执行下面的代码时,对象上下文抛出一个异常,说," ObjectStateManager中已存在具有相同键的对象。 ObjectStateManager无法使用相同的键"
跟踪多个对象这怎么可能?我的ObjectContext是全新的,我只附加一个实体(注意:实体1和2都存在于数据库中)。我试图寻找答案,但我发现的关于这类问题的所有例子都没有使用博客。)
public class Foo{
public int Id{get;set;}
public string Bar{get;set;}
}
public void Bar(Foo foo){
using(var ctx = new MyContext()){
ctx.Foos.Attach(foo); //Throws ObjectStateManager exception, at 2nd call
foo.Bar = "Bar";
ctx.SaveChanges();
}
};
public void Main(){
var foo = new Foo{Id=1,Bar="bar"};
Bar(foo); // Passes
Bar(foo); // Throws exception
}
如果我检查,如果实体是否附加,则返回false。 (这对我来说似乎很正常,因为上下文是新创造的)。然而,当我尝试附加它时,它仍然会在这种情况下引发异常,但是,上下文是新的,实体没有附加。
public void Bar2(Foo foo){
using(var ctx = new MyContext()){
if(db.Entry(foo).State == EntityState.Detached) // Returns true!!!
ctx.Foos.Attach(foo); // Executes this line as well, and still throws exception (after 2nd call)
foo.Bar = "Bar2";
ctx.SaveChanges();
}
};
public void Main2(){
var foo = new Foo{Id=2,Bar="bar2"};
Bar2(foo); // Passes
Bar2(foo); // Throws exception
}
这怎么可能,我该怎么做才能避免呢?我真的需要分离我附加的每一个poco吗?
更新:MyContext.cs的内容:
public MyContext(): base("name=MyEntities")
{
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += ObjectContext_OnObjectMaterialized;
}
protected override void Dispose(bool disposing)
{
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized -= ObjectContext_OnObjectMaterialized;
base.Dispose(disposing);
}
private void ObjectContext_OnObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{
var entity = e.Entity as Model;
if (entity == null) return;
entity.Initialized();
}