第二次调用相同的DbContext导致错误’DbContext已被处置’

我想做什么

public void SomeTestMethod(){ var person = this.PersonManager.Get(new Guid("someguid")); person.Lastname = "Jameson"; this.PersonManager.Save(person); // This goes wrong } 

哪里出错了

上面的save方法调用此代码:

 protected void Add(T source, MyEntities context, bool isNew) where T : class { if (isNew) { context.Set().Add(source); } else { var entry = context.Entry(source); if (entry.State == EntityState.Detached) { context.Set().Attach(source); entry.State = EntityState.Modified; } } } 

var entry = context.Entry(source); line是导致此错误的行:

由于已经处理了DbContext,因此无法完成操作。

我已经看到了类似问题的答案,建议使用.ToList()(或其他东西来执行链接),但这已经发生,因为Get返回一个DTO对象。

一些背景

保存中使用的PersonManager使用它来设置DbContext:

 var context = new MyEntities(); this.PersonRepository = repositoryProvider.GetRepositoryByType(context); 

var context = new MyEntities(); 只是为了让它现在正常工作,这将是DI注入。

这又取决于这个:

 public T GetRepositoryByType(MyEntities context) where T : IContextDependent { var instance = this.Repositories.SingleOrDefault(x => x is T); instance.SetContext(context); return (T)instance; } 

由于使用了相同的PersonManager ,事实上使用相同的PersonRepository (因此使用相同的上下文) ,所以我不明白为什么它会在第二次调用时处理掉。

你没有给出你在哪里创建上下文的上下文,但我假设它在一个方法中,也许是构造函数。 您的上下文的范围限定为该方法,因此GC可以在方法调用结束时自由处理它。 我认为它完全有效,甚至只有一次这样的事实,就是你在收集垃圾之前就已经成功了。

具有讽刺意味的是,您的问题正在发生,因为您还没有使用DI。 只需注入它就足以解决问题。 至少,您的上下文应限定在与PersonManager相同的级别。