多少存储库太多了?

How many repositories is too many?

我们正准备模块化一个大型企业应用程序,该应用程序当前使用的是垂死的技术堆栈。我的问题是工作模式的 Repository/Unit 中,一个工作单元中可以有多少个存储库?举例来说,我们在公开 50 多个存储库实体的单个 DbContext 上创建了一个 UnitOfWork。这会导致性能问题吗?

我们正在考虑将其拆分,以便每个模式都有自己的 DbContext,但这似乎增加了很多复杂性,并且不允许在模式之间轻松连接数据。我觉得在一个 context/unit 的工作中创建所有内容是易用性和可维护性的最佳答案,但我担心性能可能是个问题。

public class UnitOfWork : IUnitOfWork
{
    private readonly AppContext _context;

    public UnitOfWork(AppContext context)
    {
        _context = context;
        Courses = new CourseRepository(_context);
        Authors = new AuthorRepository(_context);
        ...
        ...            
        // Will lots of repositories here cause a performance problem?
        ...
        ...
        ...
        ...
        ...
    }

    public ICourseRepository Courses { get; private set; }
    public IAuthorRepository Authors { get; private set; }
    ...
    ...

    public int Complete()
    {
        return _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

它已经有几年历史了,但我已经将 UnitOfWork 与 GenericRepository 一起使用,并且没有遇到任何重大的性能问题。这与一个繁忙网站的 100 多个数据库表相关联。 也就是说,该网站还自始至终使用 Dapper Micro-ORM,因为它速度非常快,并且可以更好地控制复杂的操作。不过对于 CRUD,下面的设置对我来说效果很好。

工作单元

public class UnitOfWork :IDisposable
{
    private DbContext _db = new DbContext();

    private GenericRepository<Table1> table1Repository;
    private GenericRepository<Table2> table2Repository;
    private GenericRepository<Table3> table3Repository;
    ...
    private GenericRepository<TableN> tableNRepository;

    public GenericRepository<Table1> Table1Repository
    {
        get
        {
            if (this.table1Repository == null)
            {
                this.table1Repository = new GenericRepository<Table1>(_db);
            }
            return table1Repository;
        }
    }

    public void Save()
    {
        _db.SaveChanges();
    }

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _db.Dispose();
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

通用存储库

public class GenericRepository<TEntity> where TEntity :class
{
    internal DbContext _db;
    internal DbSet<TEntity> dbSet;

    public GenericRepository(DbContext _db)
    {
        this._db = _db;
        this.dbSet = _db.Set<TEntity>();
    }

    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query);
        }
        else
        {
            return query;
        }
    }

    public virtual TEntity GetByID(object id)
    {
        return dbSet.Find(id);
    }

    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        Delete(entityToDelete);
    }

    public virtual void Delete(TEntity entityToDelete)
    {
        if (_db.Entry(entityToDelete).State == EntityState.Detached)
        {
            dbSet.Attach(entityToDelete);
        }
        dbSet.Remove(entityToDelete);
    }

    public virtual void Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);
        _db.Entry(entityToUpdate).State = EntityState.Modified;
    }

}

用法

var unitOfWork = new UnitOfWork();

List<Table1> list = unitOfWork.Table1Repository.Get(n => n.addedOn <= DateTime.Now);

Table1 item = unitOfWork.Table1Repository.GetById(1);

unitOfWork.Table1Repository.Insert(object);
unitOfWork.Save();

unitOfWork.Table1Repository.Update(object);
unitOfWork.Save();

unitOfWork.Table1Repository.Delete(1);
unitOfWork.Save();

unitOfWork.Table1Repository.Delete(object);
unitOfWork.Save();