.Net Core之仓储(Repository)模式
Wader008 人气:0我们经常在项目中使用仓储(Repository)模式,来实现解耦数据访问层与业务层。那在.net core使用EF core又是怎么做的呢?
现在我分享一下我的实现方案:
一、在领域层创建Repository类。
1、首先定义实体接口 。
1 /// <summary> 2 /// Entity接口 3 /// </summary> 4 /// <typeparam name="TId"></typeparam> 5 public interface IEntityBase<TId> 6 { 7 /// <summary> 8 /// 默认主键字段是F_Id 9 /// </summary> 10 TId F_Id { get; } 11 }
2、其次定义实体父类。
1 /// <summary> 2 /// Entity父类 3 /// </summary> 4 public abstract class EntityBase : EntityBase<long>//默认字段类型是long 5 { 6 } 7 8 public abstract class EntityBase<TId> : IEntityBase<TId> 9 { 10 /// <summary> 11 /// 默认主键字段是F_Id 12 /// </summary> 13 public virtual TId F_Id { get; set; } 14 }
3、再次定义Repository接口,指定新增、删除等方法。
1 /// <summary> 2 /// Repository接口 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 /// <typeparam name="TId"></typeparam> 6 public interface IRepository<T, TId> where T : IEntityBase<TId> 7 { 8 /// <summary> 9 /// 事务 10 /// </summary> 11 /// <returns></returns> 12 IDbContextTransaction BeginTransaction(); 13 14 /// <summary> 15 /// 查询 16 /// </summary> 17 /// <returns></returns> 18 IQueryable<T> Query(); 19 20 /// <summary> 21 /// 新增 22 /// </summary> 23 /// <param name="entity"></param> 24 void Add(T entity); 25 26 /// <summary> 27 /// 批量新增 28 /// </summary> 29 /// <param name="entity"></param> 30 void AddRange(IEnumerable<T> entity); 31 32 /// <summary> 33 /// 删除 34 /// </summary> 35 /// <param name="entity"></param> 36 void Delete(T entity); 37 38 /// <summary> 39 /// 修改,不需要 40 /// </summary> 41 //void Update(T entity); 42 43 /// <summary> 44 /// 同步保存 45 /// </summary> 46 /// <param name="entity"></param> 47 void Save(); 48 49 /// <summary> 50 /// 异步保存 51 /// </summary> 52 /// <returns></returns> 53 Task SaveAsync(); 54 55 56 } 57 58 // <summary> 59 /// Repository接口,默认主键类型是long 60 /// </summary> 61 /// <typeparam name="T"></typeparam> 62 public interface IRepository<T> : IRepository<T, long> where T : IEntityBase<long> 63 { 64 }
4、最后实现Repository类。
1 /// <summary> 2 /// Repository实现类 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 /// <typeparam name="TId"></typeparam> 6 public class Repository<T, TId> : IRepository<T, TId> where T : class, IEntityBase<TId> 7 { 8 /// <summary> 9 /// DB上下文 10 /// </summary> 11 private DemoDbContext Context { get; } 12 13 /// <summary> 14 /// 实体集合 15 /// </summary> 16 private DbSet<T> DbSet { get; } 17 18 public Repository(DemoDbContext context) 19 { 20 Context = context; 21 DbSet = Context.Set<T>(); 22 } 23 24 /// <summary> 25 /// 事务 26 /// </summary> 27 /// <returns></returns> 28 public IDbContextTransaction BeginTransaction() 29 { 30 return Context.Database.BeginTransaction(); 31 } 32 33 /// <summary> 34 /// 查询 35 /// </summary> 36 /// <returns></returns> 37 public IQueryable<T> Query() 38 { 39 return DbSet; 40 } 41 42 /// <summary> 43 /// 新增 44 /// </summary> 45 /// <param name="entity"></param> 46 public void Add(T entity) 47 { 48 DbSet.Add(entity); 49 } 50 51 /// <summary> 52 /// 批量新增 53 /// </summary> 54 /// <param name="entity"></param> 55 public void AddRange(IEnumerable<T> entity) 56 { 57 DbSet.AddRange(entity); 58 } 59 60 /// <summary> 61 /// 删除 62 /// </summary> 63 /// <param name="entity"></param> 64 public void Delete(T entity) 65 { 66 DbSet.Remove(entity); 67 } 68 69 /// <summary> 70 /// 同步保存 71 /// </summary> 72 public void Save() 73 { 74 Context.SaveChanges(); 75 } 76 77 /// <summary> 78 /// 异步保存 79 /// </summary> 80 /// <returns></returns> 81 public Task SaveAsync() 82 { 83 return Context.SaveChangesAsync(); 84 } 85 86 } 87 88 // <summary> 89 /// Repository实现类,默认主键类型是long 90 /// </summary> 91 /// <typeparam name="T"></typeparam> 92 public class Repository<T> : Repository<T, long>, IRepository<T> where T : class, IEntityBase<long> 93 { 94 public Repository(DemoDbContext context) : base(context) 95 { 96 } 97 }
二、按上面操作将Repository创建OK后,现在用它实现一个简单的数据操作。
1、新增account实体。
1 /// <summary> 2 /// 账号实体 3 /// </summary> 4 public class Account : EntityBase 5 { 6 /// <summary> 7 /// 账号 8 /// </summary> 9 public string F_Account { get; set; } 10 11 /// <summary> 12 /// 密码 13 /// </summary> 14 public string F_Password { get; set; } 15 16 /// <summary> 17 /// 最后登入时间 18 /// </summary> 19 public DateTime? F_LastLoginTime { get; set; } 20 21 }
2、创建用户服务接口。
1 /// <summary> 2 /// 用户服务接口 3 /// </summary> 4 public interface IUserService 5 { 6 /// <summary> 7 /// 获取账号 8 /// </summary> 9 /// <param name="account"></param> 10 /// <returns></returns> 11 Task<Account> GetAccountMsg(string account); 12 13 /// <summary> 14 /// 更新账号最后一次登入时间 15 /// </summary> 16 /// <param name="account"></param> 17 /// <returns></returns> 18 Task UpdateLoginTime(Account account); 19 20 } 21 }
3、实现用户服务类。
1 /// <summary> 2 /// 用户服务类 3 /// </summary> 4 public class UserService : IUserService 5 { 6 7 private readonly IRepository<Account> accountRepository; 8 9 10 public UserService(IRepository<Account> accountRepository) 11 { 12 this.accountRepository = accountRepository;//注入仓储类 13 14 } 15 16 17 /// <summary> 18 /// 获取账号 19 /// </summary> 20 /// <param name="account"></param> 21 /// <returns></returns> 22 public async Task<Account> GetAccountMsg(string account) 23 { 24 return await accountRepository.Query().Where(t => t.F_Account == account).FirstOrDefaultAsync(); 25 } 26 27 /// <summary> 28 /// 更新账号最后一次登入时间 29 /// </summary> 30 /// <param name="account"></param> 31 /// <returns></returns> 32 public async Task UpdateLoginTime(Account account) 33 { 34 account.F_LastLoginTime = DateTime.Now; 35 await accountRepository.SaveAsync(); 36 } 37 }
4、至于DbContext的实现类(也就是上面代码提到的DemoDbContext),以及在Startup.cs注入服务类和仓储类,这些都很简单,就不放代码上来了。
5、最后,在Controller类里调用用户服务类,完成!
[HttpPost] public async Task<IActionResult> TryLogin(string account, string password) { //查询账号信息 var accountEty = await userService.GetAccountMsg(account); if (accountEty != null) { if (password == accountEty.F_Password) { //更新账号最后一次登录时间 await userService.UpdateLoginTime(accountEty); return Json(new { state = "success", message = "登录成功" }); } else { return Json(new { state = "error", message = "密码不正确,请重新输入" }); } } else { return Json(new { state = "error", message = "账号不存在,请重新输入" }); } }
三、现总结一下在servcie类怎样使用仓储类实现对单一实体的各种操作。
a、查询:
1 _repository.Query().Where(xx).FirstOrDefaultAsync();
b、新增:
1 _repository.Add(xx) or AddRange(xx); 2 _repository.SaveAsync();
c、删除:
1 _repository.Delete(xx); 2 _repository.SaveAsync();
d、更新:
1 实体对象.属性=new value; 2 _repository.SaveAsync();
e、事务:
1 using (var transaction = _repository.BeginTransaction()) 2 { 3 ... ... 4 _repository.SaveChanges();
5 ... ...
6 _server.xxx(); 7 transaction.Commit(); 8 }
四、深知自己水平有限,写的不妥之处还望见谅,也欢迎院子各路大路批评指正,谢谢。
参考文章:
a、【.Net设计模式系列】仓储(Repository)模式 ( 一 )
b、 Repository模式
加载全部内容