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)

{

  Table.Update(entity);

  return persist ? SaveChanges : 0;

}

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

{

  Table.UpdateRange(entities);

  return persist ? SaveChanges : 0;

}

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

{

  Table.Remove(entity);

  return persist ? SaveChanges : 0;

}

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

{

  Table.RemoveRange(entities);

  return persist ? SaveChanges : 0;

}

Есть еще один метод удаления, который не следует этому шаблону. Для выдачи операции удаления он использует EntityState, что часто происходит при работе с ASP.NET Core с целью сокращения сетевого трафика:

public int Delete(int id, byte[] timeStamp, bool persist = true)

{

  var entity = new T {Id = id, TimeStamp = timeStamp};

  Context.Entry(entity).State = EntityState.Deleted;

  return persist ? SaveChanges : 0;

}

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

<p id="AutBody_Root995"><strong>Интерфейсы хранилищ, специфичных для сущностей</strong></p>

Каждая сущность будет иметь строго типизированное хранилище, производное от BaseRepo, и интерфейс, который реализует IRepo. Создайте в каталоге Repos проекта AutoLot.Dal новый каталог по имени Interfaces и добавьте в него пять файлов интерфейсов:

ICarRepo.cs

ICreditRiskRepo.cs

ICustomerRepo.cs

IMakelRepo.cs

IOrderRepo.cs

Содержимое интерфейсов будет представлено в последующих разделах.

<p id="AutBody_Root996"><strong>Интерфейс хранилища данных об автомобилях</strong></p>

Откройте файл ICarRepo.cs и поместите в его начало такие операторы using:

using System.Collections.Generic;

using AutoLot.Models.Entities;

using AutoLot.Dal.Repos.Base;

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

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