Entity Framework 4 ObjectContext Lifetime - PullRequest
       31

Entity Framework 4 ObjectContext Lifetime

2 голосов
/ 29 июля 2010

Я только начал использовать EF4 с шаблоном хранилища. Мне приходится вызывать метод dispose после каждого использования контекста или обтекания кода в блоке using. Могу ли я использовать ObjectContext, не делая этого в каждом написанном мною методе, или есть лучший способ обработки этого в хранилище.
Также я не хочу передавать ObjectContext в хранилище из пользовательского интерфейса.

Ответы [ 2 ]

5 голосов
/ 29 июля 2010

Чтобы сделать это как можно более эффективным ресурсом без внедрения зависимостей, я бы предложил вам реализовать частное свойство с отложенной загрузкой для контекста объекта.

private ObjectContext _context;
private ObjectContext Context 
{ get 
    { 
        return _context ?? (_context = new ObjectContext()); 
    }
}

Далее, сделайте ваш репозиторий реализующим IDisposable и позаботьтесь о контексте объекта в вашем методе dispose:

public Repository : IDisposable
{
     ...
     public void Dispose()
     {
         _context.Dispose();
     }
}

Затем вы просто используете свойство во всех ваших методах и включаете использование вашего репозитория в using операторов.

Чтобы уменьшить трафик в базу данных, вы также можете выделить сохранение в отдельный метод в хранилище, который просто перенаправляет вызов в контекст объекта. Таким образом, вы получаете больше контроля над , когда данные сохраняются в слое пользовательского интерфейса, даже если вы не контролируете how . Это означает, что вы могли бы сделать

using (var repo = new Repository())
{
    repo.AddSomeStuff("this", "is", true);
    repo.ChangeSomethingElse("yes, please");
    repo.Save();
}

и будет только один вызов из EF в базу данных. С другой стороны, если вы делаете

using (var repo = new Repository())
{
    repo.AddSomeStuff("this", "is", true);
    repo.ChangeSomethingElse("yes, please");
}

ничего не происходит, что может сбить с толку.

2 голосов
/ 29 июля 2010

Общий шаблон для использования контекста объекта:

public BusinessObject GetSomething(){
   using (MyObjectContext context = new MyObjectContext()){
      //..do fun stuff
   }

}

Который, надеюсь, является шаблоном, который вы используете. Вызов dispose кажется немного излишним, когда вы можете просто использовать выражение «using».

Другой вариант, если вы собираетесь выполнять несколько запросов к БД в потоке. Я видел шаблон, где вы можете повторно использовать тот же контекст в потоке. Люди в основном реализуют одноэлементный шаблон на основе потоков и передают контекст. Преимущества этого не в том, чтобы перестраивать контекст, а в некоторых случаях в кэшировании памяти. Недостатком является то, что вы можете столкнуться с проблемами параллелизма. Кто-то обновляет что-то, что вы внутренне кэшировали в EF.

Полагаю, что второй случай на самом деле не применим, потому что, похоже, вы пишете маленькое приложение. (это утверждение было основано на ваших комментариях о передаче контекста из пользовательского интерфейса ... заявление, которое испугает любого хорошего архитектора кода).

Если вы заинтересованы в синглтоне на основе потоков. Сначала изучите шаблон Singleton , а затем ознакомьтесь с этим блогом о потоках «DataContext». Вам придется изменить тип «DataContext» на класс ObjectContext, но он будет работать.

РЕДАКТИРОВАТЬ

Я скажу, что упустил очевидное решение, и это было бы ниже;). Просто используйте свойство Object Context и воспроизводите ваш репозиторий в операторе using. Это было бы так же, как в примере использования выше, но вы бы реализовали IDisoposable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...