UnitOfWork + Шаблон репозитория - Добавление собственного репозитория - PullRequest
0 голосов
/ 03 июня 2018

Я слежу за этим примером :

Сущностями

[Table("Authors")]
public class Author {
    [Key]
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Book> Books { get; set; }
}
[Table("Books")]
public class Book {
    [Key]
    public int ID { get; set; }
    public string Title { get; set; }
    public int Author_ID { get; set; } 

    [ForeignKey("Author_ID")] 
    public virtual Author Author { get; set; }
}

DbContext

public class MyDbContext : DbContext
{
    public virtual DbSet<Author> Authors { get; set; }
    public virtual DbSet<Book> Books { get; set; }
    public MyDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
    }
}

Общий репозиторий

public interface IRepository<T> where T : class
{
   IQueryable<T> Entities { get; }
   void Remove(T entity);
   void Add(T entity);
}
public class GenericRepository<T> : IRepository<T> where T : class
{
    private readonly MyDbContext _dbContext;
    private IDbSet<T> _dbSet => _dbContext.Set<T>();
    public IQueryable<T> Entities => _dbSet;
    public GenericRepository(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }
    public void Remove(T entity)
    {
        _dbSet.Remove(entity);
    }
    public void Add(T entity)
    {
        _dbSet.Add(entity);
    }
}

UnitOfWork

public interface IUnitOfWork
{
    IRepository<Author> AuthorRepository { get; }
    IRepository<Book> BookRepository { get; }

    /// <summary>
    /// Commits all changes
    /// </summary>
    void Commit();
    /// <summary>
    /// Discards all changes that has not been commited
    /// </summary>
    void RejectChanges();
    void Dispose();
}
public class UnitOfWork : IUnitOfWork
{
    private readonly MyDbContext _dbContext;
    #region Repositories
    public IRepository<Author> AuthorRepository => 
       new GenericRepository<Author>(_dbContext);
    public IRepository<Book> BookRepository => 
       new GenericRepository<Book>(_dbContext);
    #endregion
    public UnitOfWork(MyDbContext dbContext)
    {
        _dbContext = dbContext;
    }
    public void Commit()
    {
        _dbContext.SaveChanges();
    }
    public void Dispose()
    {
        _dbContext.Dispose();
    }
    public void RejectChanges()
    {
        foreach (var entry in _dbContext.ChangeTracker.Entries()
              .Where(e => e.State != EntityState.Unchanged))
        {
            switch (entry.State)
            {
                case EntityState.Added:
                    entry.State = EntityState.Detached;
                    break;
                case EntityState.Modified:
                case EntityState.Deleted:
                    entry.Reload();
                    break;
            }
        }
    }
}

Вопрос

Что делать, если мне нужна пользовательская функция добавления?Если я добавлю свойство Code в свой класс Book:

[Table("Books")]
public class Book {
    [Key]
    public int ID { get; set; }
    public string Title { get; set; }
    public int Author_ID { get; set; } 
    public string Code { get; set; } //I'm adding a Code property here

    [ForeignKey("Author_ID")] 
    public virtual Author Author { get; set; }
}

и захочу автозаполнить свойство Code перед вставкой объекта Book в БД.Я думаю, мне нужно создать «пользовательский» BookRepository , который наследует GenericRepository и переопределить функцию Add , чтобы получить что-то подобное:

public void Add(Book entity)
    {
        entity.Code = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds+entity.Title.Replace(" ","");
        _dbSet.Add(entity);
    }

Я не знаком с концепциями шаблона проектирования / наследования / интерфейса.Можно ли сделать что-то подобное?

1 Ответ

0 голосов
/ 12 сентября 2018

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

Я написал статью о том, как вы планируете Тонкий репозиторий и единицу работы, используя EF

Я вставлю ссылку ниже https://www.codeproject.com/Articles/1157241/Very-Thin-Database-Layer-using-UnitOfWork-Pattern

Надеюсь, это поможет

...