【问题标题】:How many repositories is too many?多少个存储库太多了?
【发布时间】:2018-03-27 22:02:48
【问题描述】:

我们正准备对一个大型企业应用程序进行模块化,该应用程序目前正在使用濒临死亡的技术堆栈。我的问题是在存储库/工作单元模式中,一个工作单元中可以有多少个存储库?例如,我们在一个 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();
    }
}

【问题讨论】:

  • 您不应该在Entity Framework 中使用UoWRepository 模式。 EF 已经实现了这些模式。
  • 确实如此,但在大型企业应用程序中,存储库/UoW 模式仍然可以用于创建一个代理层,封装所有处理 ORM 的代码,这样应用程序就不会直接暴露给 ORM .这创建了非常清晰的关注点分离,允许在不更改任何应用程序代码的情况下更轻松地过渡到另一个 ORM。

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


【解决方案1】:

现在已经有几年了,但我已经使用了带有 GenericRepository 的 UnitOfWork 并且没有遇到任何重大的性能问题。这与一个繁忙网站的 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();

【讨论】:

  • 这是管理与此模式相关的成本的最佳方法之一,因为只有在使用单个存储库时才会创建它
猜你喜欢
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 2010-09-13
  • 2011-05-26
  • 1970-01-01
  • 2010-12-26
  • 2010-12-27
相关资源
最近更新 更多