Создание контекста в LINQ to Entities - PullRequest
26 голосов
/ 02 мая 2009

Я видел два разных подхода к программистам при создании контекста сущности в своем коде.

Первый такой, и вы можете найти его во всех примерах кода MSDN:

public void DoSomething() {
     using (TaxableEducationEntities context = new TaxableEducationEntities()) {
          // business logic and whatever else
     }
}

Вторым является создание контекста как частного атрибута в некотором классе, который инкапсулирует вашу бизнес-логику. Таким образом, у вас будет что-то вроде:

public class Education_LINQ {

        private TaxableEducationEntities context = new TaxableEducationEntities();

        public void DoSomething() {
            var result = from a in context.luAction
                         select a;

            // business logic and whatever else
        }
}

Какой способ более эффективен?

Предположим, что у вас есть два метода, один с именем DoSomething1 () и другой с именем DoSomething2 (), и оба метода включают в себя оператор using, чтобы открыть контекст и делать с ним что угодно. Если бы вы вызывали один метод за другим, будут ли происходить какие-то лишние издержки, поскольку по сути оба метода создают контекст, а затем очищают его, когда все готово? В отличие от наличия только одного закрытого атрибута, который создается, когда создается экземпляр объекта класса, а затем очищается, когда объект выходит из области видимости?

Ответы [ 2 ]

40 голосов
/ 02 мая 2009

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

Эти издержки относительно незначительны, поэтому часто о них не стоит беспокоиться, особенно если учесть дополнительную безопасность, присущую шаблону использования.

Для меня, какой вариант вы выберете, зависит от таких вещей, как:

  1. Как долго прожил ваш класс упаковки может быть? Если это живет для долгое время ObjectContext может расти, чтобы держать много сущностей замедляется со временем. Итак, новый ObjectContext каждый раз может быть хорошая идея.
  2. Являются ли звонки на методы в вашем классе упаковки синхронизируется? ObjectContext сам класс не является потокобезопасным, так что если Вы используете второй шаблон, который вам нужен чтобы убедиться, что ваш класс упаковки / хранилище является потокобезопасным, если вы ожидайте, что несколько потоков будут вызывать его.
  3. Методы по существу не связаны? Если это так, вы можете получить неожиданные побочные эффекты, если они разделяют один контекст между методами.

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

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

ОБНОВЛЕНИЕ: я нашел время, чтобы собрать более полный ответ

0 голосов
/ 02 мая 2009

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

public class UserManagerRepository : IUserManagerRepository, IDisposable
{
    private readonly Entities _context = new Entities();
    private bool _disposed;

    public User Create(User user, int countryId)
    {
        user.Country = GetCountry(countryId);
        _context.AddToUser(user);
        _context.SaveChanges();
        return user;
    }
}

Затем, чтобы использовать этот репозиторий, я делаю что-то вроде:

using(var repository = new UserManagerRepository())
{
    repository.Create(user);
}
...