2015-12-15 3 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: Правильно, как предоставлено «ManManager», которое их запускает. – Spikee

ответ

3

Вы не указали контекст того, где вы создаете свой контекст, но я предполагаю, что это метод, возможно, конструктор. Ваш контекст привязан к этому методу, поэтому GC может свободно распоряжаться им, когда заканчивается вызов метода. Я думаю, что тот факт, что он вообще работает, даже когда-то, заключается в том, что вы ударяете его, прежде чем собирать мусор.

По иронии судьбы, ваша проблема возникает из-за того, что вы еще не используете DI. Простое инъектирование было бы достаточно вероятным для решения проблемы. По крайней мере, ваш контекст должен быть ограничен тем же уровнем, что и PersonManager.

+0

Правильно, я использую инъекцию конструктора. См. Мое обновление относительно DI. – Spikee

+0

GC никогда никогда не называет '.Dispose()'. GC может вызывать финализатор и может явным образом вызывать '.Dispose()', но в большинстве случаев GC не запускает dispose. – Enigmativity

+0

@ Энигматичность: Я не говорил буквально. Я только имел в виду, что контекст в конечном итоге удаляется работой GC, не обязательно, что GC на самом деле называется Dispose. –

Смежные вопросы