多种仓储模式
IBaseRepository + BaseRepository 模式(适用于小项目,扩展性差)
- IRepository接口包含了基本的CRUD操作,如果业务中还需要扩展其他操作,只需在IRepository接口中添加。
- Repository实现了IRepository接口。其中ISqlHelp接口包含获取数据库链接字符串的功能,_context为EF或EF Core类库。
- 优点是简单、快速,缺点是扩展性差且违反开放-关闭原则(Open-Close Principle)
IBaseRepository.cs
1 2 3 4 5 6 7 8 9 10 11
| public interface IBaseRepository<T> where T : class, new() { T Create(T model); T Update(T model); T Query(Guid guid); T Query(Espression<Func<T, bool>> expression); int Delete(Guid guid); int BatchDelete(IList<Guid> guids); List<T> GetAll(); List<T> GetAll(Expression<Func<T, bool>> expression, Expression<Func<T, dynamic>> sortPredicate, SortOrder sortOrder, int skip, int take, out int total); }
|
BaseRepository.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| public class BaseRepository<T> : IBaseRepository<T> where T : class, new() { internal DbContext _context;
public BaseRepository(DbContext context) { _context = context }
public T Create(T model) { _context.Entry(model).State = EntityState.Added; var createRowCount = _context.SaveChanges(); return createRowCount > 0 ? model : null; }
public T Update(T model) { _context.Entry(model).State = EntityState.Modified; var updateRowAcount = _context.SaveChanges(); return updateRowAcount > 0 ? model : null; }
public T Query(Guid guid) { return _context.Set<T>().Find(guid); }
public T Query(Expression<Func<T, bool>> expression) { return _context.Set<T>().FirstOrDefault(expression); }
public int Delete(Guid guid) { var model = _context.Set<T>().Find(guid); if (model == null) { throw new ArgumentOutOfRangeException(nameof(guid)); } _context.Entry(model).State = EntityState.Deleted; return _context.SaveChanges(); }
public int BatchDelete(IList<Guid> guids) { foreach (var item in guids) { var model = _context.Set<T>().Find(item); _context.Entry(model).State = EntityState.Deleted; } return _context.SaveChanges(); }
public List<T> GetAll() { return _context.Set<T>().Where(q => true).ToList(); }
public List<T> GetAll(Expression<Func<T, bool>> expression, Expression<Func<T, dynamic>> sortPredicate, SortOrder sortOrder, int skip, int take, out int total) { total = _context.Set<T>().Where(expression).Count(); switch (sortOrder) { case SortOrder.Ascending: return _context.Set<T>().Where(expression).OrderBy(sortPredicate).Skip(skip).Take(take).ToList(); case SortOrder.Descending: return _context.Set<T>().Where(expression).OrderByDescending(sortPredicate).Skip(skip).Take(take).ToList(); } throw new InvalidOperationException("分页查询必须指定排序字段和排序顺序。"); } }
|
AdminServer.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public sealed class AdminServer { private readonly IBaseRepository<User> _adminRepository;
public AdminServer(IBaseRepository<User> adminRepository) { _adminRepository = adminRepository; }
public void CreateUser() { var admin = new User(); _adminRepository.Create(admin); } }
|
IBaseRepository+BaseRepository+IRepository+Repository(可扩展性好,未处理并发)
将BaseRepository.cs的实现方法上加上virtual关键字,使方法可以重载,每添加一个实体,需要添加对应的接口和实现
BaseRepository.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| public class BaseRepository<T> : IBaseRepository<T> where T : class, new() { internal DbContext _context; public BaseRepository(DbContext context) { _context = context }
public virtual T Create(T model) { }
public virtual T Update(T model) { }
public virtual T Query(Guid guid) { }
public virtual T Query(Expression<Func<T, bool>> expression) { }
public virtual int Delete(Guid guid) { }
public virtual int BatchDelete(IList<Guid> guids) { }
public virtual List<T> GetAll() { }
public virtual List<T> GetAll(Expression<Func<T, bool>> expression, Expression<Func<T, dynamic>> sortPredicate, SortOrder sortOrder, int skip, int take, out int total) { } }
|
IRepository.cs
1 2 3 4 5 6 7 8
| public partial interface IAdminRepository : IBaseRepository<Admin> { bool IsExist(Admin admin); } public partial interface IUserRepository : IBaseRepository<User> {
}
|
Repository.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public partial class AdminRepository : BaseRepository<Admin>,IAdminRepository { public AdminRepository(ISqlHelp sqlHelp) : base(sqlHelp) {
} public bool IsExist(Admin admin) { } } public partial class UserRepository : BaseRepository<User>,IUserRepository { public UserRepository(ISqlHelp sqlHelp) : base(sqlHelp) {
} }
|
AdminServer.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public sealed class AdminServer { private readonly IAdminRepository _adminRepository;
public AdminServer(IAdminRepository adminRepository) { _adminRepository = adminRepository; }
public void CreateUser() { var admin = new User(); _adminRepository.Create(admin); }
public bool IsExist(Admin admin) { return _adminRepository.IsExist(admin); } }
|
仓储模式+工作单元模式(扩展性高,有并发处理需求)
使用工作单元的原因是可以提高数据库写操作负载,并且在仓储模式中可以根据不同的数据库链接字符串读不同的库。
IUnitOfWork.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public interface IUnitOfWork : IDisposable { _context _context { get; set; }
Task CommitAsync(); #region Methods void RegisterNew<T>(T obj) where T : class, IEntity;
void RegisterModified<T>(T obj) where T : class;
void RegisterDeleted<T>(T obj) where T : class; #endregion }
|
UnitOfWork.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| public class UnitOfWork : IUnitOfWork { public _context _context { get; set; } public UnitOfWork(IContextHelper contextHelp) { _context = contextHelp._context; } private AdminRepository _adminRepository;
public AdminRepository AdminRepository { get { return _adminRepository ?? new AdminRepository(_context); } }
public virtual async Task CommitAsync() { try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException ex) { ex.Entries.Single().Reload(); } } public virtual void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!disposing) { return; } if (_context == null) { return; } _context.Dispose(); _context = null; }
public virtual void RegisterNew<TEntity>(TEntity obj) where TEntity : class, IEntity { _context.Set<TEntity>().Add(obj); }
public virtual void RegisterModified<TEntity>(TEntity obj) where TEntity : class { _context.Entry(obj).State = EntityState.Modified; }
public virtual void RegisterDeleted<TEntity>(TEntity obj) where TEntity : class { _context.Entry(obj).State = EntityState.Deleted; }
}
|
AdminServer.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class AdminServer { private UnitOfWork unit;
public AdminServer(UnitOfWork unitOfWork) { unit = unitOfWork; }
public IEnumerable Get() { return unit.AdminRepository.GetAll(); } }
|