2015-12-15 23 views
3

我试图做以相同的DbContext第二个电话会导致错误“的DbContext已配置”

public void SomeTestMethod(){ 
    var person = this.PersonManager.Get(new Guid("someguid")); 

    person.Lastname = "Jameson"; 

    this.PersonManager.Save(person); // This goes wrong 
} 

如果它出错

上述保存方法调用的代码:

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

      entry.State = EntityState.Modified; 
     } 
    } 
} 

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

The operation cannot be completed because the DbContext has been disposed.

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

一些背景

PersonManager在保存时,使用此设置的DbContext:

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

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

而这又取决于这一点:

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

    instance.SetContext(context); 

    return (T)instance; 
} 

由于使用了相同的PersonManager,事实上同PersonRepository用于(并因此同样的情况下),所以不看看它为什么会在第二次电话中处理。

+0

你的Get和Save都使用'PersonRepository'吗? –

+0

@AlexanderDerck:正确,由运行它们的'PersonManager'提供。 – Spikee

回答

3

你还没有给出你创建你的上下文的地方,但我假设它在一个方法中,也许是构造函数。你的上下文被限制在那个方法中,所以当方法调用结束时,GC可以自由处理它。我认为,即使只有一次,它都可以工作的事实是,在垃圾收集之前,你已经设法击中它。

具有讽刺意味的是,你的问题正在发生,因为你还没有使用DI。简单地注入就足以解决问题。至少,您的背景应与PersonManager的范围相同。

+0

正确,我正在使用构造函数注入。请参阅关于DI的更新。 – Spikee

+0

GC永远不会直接调用'.Dispose()'。 GC可能会调用一个终结器,并可能会显式调用'.Dispose()',但在大多数情况下,GC不会触发dispose。 – Enigmativity

+0

@Enigmativity:我没有字面上的意思。我只是意味着上下文最终由GC的工作处理,不一定GC实际上称之为“Dispose”。 –