问题
We are getting ready to modularize a large enterprise application that is currently using a dying stack of technologies. My question is in the Repository/Unit of Work pattern, how many Repositories can you have in a unit of work? Say for example we create a UnitOfWork on a single DbContext that exposes 50+ repository entities. Will this cause performance problems?
We were looking at maybe splitting it up so that each schema has it's own DbContext but this seems to add a lot of complexity and then doesn't allow for easy joining of data between the schemas. I feel like creating everything under one context/unit of work is the best answer for ease of use and maintainability but I am concerned performance may be a problem.
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:
It's a few years old now but I've used a UnitOfWork with a GenericRepository and not suffered any major performance issues. This is hooked into over 100 DB tables of a busy website. That said, the website in question also employs the Dapper Micro-ORM throughout as it's very fast and gives more control on complex operations. For CRUD though, the setup below works well for me.
Unit Of Work
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);
}
}
Generic Repository
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;
}
}
Usage
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();
来源:https://stackoverflow.com/questions/49523150/how-many-repositories-is-too-many