多少存储库太多了?
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();
我们正准备模块化一个大型企业应用程序,该应用程序当前使用的是垂死的技术堆栈。我的问题是工作模式的 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();