EF множественные CRUD

251
01 июля 2017, 08:32

Есть несколько моделей и для них BusinessContext в котором описаны CRUD операции. По сути они одни, только меняются таблицы

public void Create(Client Client)
        {
            _context.Clients.Add(Client);
            _context.SaveChanges();
        }
        public void Update(Client Client)
        {
            var entity = _context.Clients.Find(Client.Id);
            if (entity == null)
            {
                throw new NotImplementedException("Объект не найден. Обработка этого исключения находится на стадии разработки");
            }
            _context.Entry(Client).CurrentValues.SetValues(Client);
            _context.SaveChanges();
        }
        public void Remove(Client Client)
        {
            _context.Clients.Remove(Client);
            _context.SaveChanges();
        }

Можно ли как-то их модифицировать, что-бы процедура сама определяла в какой таблице работать? Т.е. если я Crete(Client); подал, то выполнится создание в таблице Clients, а если Create(Visit) то в таблице Visits

Answer 1

Как вариант можно сделать обобщенный класс с заготовками CRUD.

Класс Crud:

public class Crud<T> : IDisposable where T: BaseModel 
{
    private readonly DbContext _context;
    public Crud()
    {
        _context = new DbContext();
    }
    public virtual void Create(T entity)
    {
        _context.Set<T>().Add(entity);
        _context.SaveChanges();
    }
    public virtual void Update(T entity)
    {
        var dbEntity = _context.Set<T>().Find(entity.Id);
        if (dbEntity == null)
        {
            throw new NotImplementedException("Объект не найден. Обработка этого исключения находится на стадии разработки");
        }
        _context.Entry(entity).CurrentValues.SetValues(entity);
        _context.SaveChanges();
    }
    public virtual void Remove(T entity)
    {
        _context.Set<T>().Remove(entity);
        _context.SaveChanges();
    }
    private bool disposed = false;
    public virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        this.disposed = true;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

Также тут используется класс BaseModel в котором будет одно поле Id и от которого мы будем наследовать модели. Это нужно для того, чтобы иметь возможность обращаться к идентификатору сущности внутри класса Crud (в методе Update).

public abstract class BaseModel
{
    public virtual int Id { get; set; }
}

Еще можете почитать про паттерн репозиторий тут.

Answer 2

Для решения вашей задачи можно воспользоваться методом DbContext.Set<T>(). Например, обобщенный метод, который добавляет сущность в БД может выглядеть так:

class DbManager
{
     private DbContext _context;
     public DbManager()
     {
          _context = new EfDbContext();
     }
     public void Create<T>(T entity) where T : class
     {
         // Лишние проверки удалены что бы не загромождать код.
         _context.Set<T>().Add(entity);
         _context.SaveChanges();
     }
}

Аналогично реализуются методы удаления и обновления.

P.S. Вместо лирического отступления.

В целом я бы вам не советовал реализовывать паттерны Repository и Unit of Work для EF, которыми так пестрит интернет, поскольку EF и так их реализует из коробки (тыц).

Где:

  • DbContext - это реализация Unit of Work.
  • DbSet - реализация Repository.
READ ALSO
Рисование карты игроком по типу Free Rider HD

Рисование карты игроком по типу Free Rider HD

Надо предоставить игроку возможность создавать игровое поле посредством рисования(пример)Ввод осуществляется исходя из координат курсора(в...

200
Аналог scanner&#39;а из java в c#

Аналог scanner'а из java в c#

Добрый день

187
Не подключается локальная служба по net.tcp

Не подключается локальная служба по net.tcp

Пробую работать с WCFСоздал службу, и хочу в клиенте ее добавить (Добавить ссылку на службу -> вставляю адрес)

282
Автоматизация Desktop приложений (связка WinForms + jar)

Автоматизация Desktop приложений (связка WinForms + jar)

Здравствуйте! Суть проекта такая: Есть приложение WinForms, которое выступает слушателем jar приложенийТ

181