对同一DbContext的第二次调用导致错误' DbContext已被处理'

时间:2015-12-15 12:30:27

标签: c# .net asp.net-mvc entity-framework

我想做的事

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>(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);行是导致此错误的行:

  

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

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

一些背景

save中使用的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,所以我不会看到为什么会在第二次电话会议中处理。

1 个答案:

答案 0 :(得分:3)

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

具有讽刺意味的是,您的问题正在发生,因为您尚未使用DI。简单地注入它就足以解决问题。至少,您的上下文的范围应与canvas = $("canvas")[0]相同。