有多少个存储库太多了?

时间:2018-03-27 22:02:48

标签: asp.net-mvc entity-framework repository unit-of-work

我们正准备模块化目前正在使用垂死堆栈技术的大型企业应用程序。我的问题是在存储库/工作单元模式中,您可以在一个工作单元中拥有多少个存储库?比如说我们在单个DbContext上创建一个UnitOfWork,它暴露了50多个存储库实体。这会导致性能问题吗?

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

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();
    }
}

1 个答案:

答案 0 :(得分:3)

现在已经有几年了,但我已经将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();