return;

  }

  if (disposing)

  {

    if (_disposeContext)

    {

      Context.Dispose();

    }

  }

  _isDisposed = true;

}

~BaseRepo()

{

  Dispose(false);

}

На свойства DbSet класса ApplicationDbContext можно ссылаться с использованием метода Context.Set(). Создайте открытое свойство по имени Table типа DbSet и установите его начальное значение в конструкторе:

public DbSet Table { get; }

protected BaseRepo(ApplicationDbContext context)

{

  Context = context;

  Table = Context.Set();

  _disposeContext = false;

}

<p id="AutBody_Root992"><strong>Реализация метода SaveChanges()</strong></p>

Класс BaseRepo имеет метод SaveChanges(), который вызывает переопределенную версию SaveChanges() и демонстрирует обработку специальных исключений. Добавьте в класс BaseRepo показанный ниже код:

public int SaveChanges()

{

  try

  {

    return Context.SaveChanges();

  }

  catch (CustomException ex)

  {

    // Подлежит надлежащей обработке -- уже зарегистрировано в журнале.

    throw;

  }

  catch (Exception ex)

  {

    // Подлежит регистрации в журнале и надлежащей обработке.

    throw new CustomException("An error occurred updating the database", ex);

  }

}

<p id="AutBody_Root993"><strong>Реализация общих методов чтения</strong></p>

Следующий комплект методов возвращает записи с применением операторов LINQ. Метод Find() принимает первичный ключ (ключи) и сначала выполняет поиск в ChangeTracker. Если сущность уже отслеживается, тогда возвращается отслеживаемый экземпляр, иначе запись извлекается из базы данных.

public virtual T? Find(int? id) => Table.Find(id);

Дополнительные два метода Find() расширяют базовый метод Find(). Приведенный далее метод демонстрирует извлечение записи, но без ее добавления в ChangeTracker, используя AsNoTrackingWithldentityResolution(). Добавьте в класс показанный ниже код:

public virtual T? FindAsNoTracking(int id) =>

  Table.AsNoTrackingWithIdentityResolution().FirstOrDefault(x => x.Id == id);

Другая вариация удаляет из сущности фильтры запросов и затем применяет сокращенную версию (пропускающую метод Where()) для получения FirstOrDefault(). Добавьте в класс следующий код:

public T? FindIgnoreQueryFilters(int id) =>

  Table.IgnoreQueryFilters().FirstOrDefault(x => x.Id == id);

Методы GetAll() возвращают все записи из таблицы. Первый метод извлекает их в порядке, поддерживаемом в базе данных, а второй по очереди обрабатывает все фильтры запросов:

public virtual IEnumerable GetAll() => Table;

public virtual IEnumerable GetAllIgnoreQueryFilters()

  => Table.IgnoreQueryFilters();

Метод ExecuteQuery() предназначен для выполнения хранимых процедур:

public void ExecuteQuery(string sql, object[] sqlParametersObjects)

  => Context.Database.ExecuteSqlRaw(sql, sqlParametersObjects);

<p id="AutBody_Root994"><strong>Реализация методов добавления, обновления и удаления</strong></p>

Далее понадобится добавить блок кода, который будет служить оболочкой для соответствующих методов добавления, обновления и удаления, связанных со специфичным свойством DbSet. Параметр persist определяет, выполняет ли хранилище вызов SaveChanges() сразу же после вызова методов добавления, обновления и удаления. Все методы помечены как virtual, чтобы сделать возможным дальнейшее переопределение. Добавьте в класс показанный ниже код:

public virtual int Add(T entity, bool persist = true)

{

  Table.Add(entity);

  return persist ? SaveChanges() : 0;

}

public virtual int AddRange(IEnumerable entities, bool persist = true)

{

  Table.AddRange(entities);

  return persist ? SaveChanges() : 0;

}

public virtual int Update(T entity, bool persist = true)

{

Перейти на страницу:

Похожие книги