.Net Core之仓储(Repository)模式
我们经常在项目中使用仓储(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类怎样使用仓储类实现对单一实体的各种操作。
1、查询:
1 _repository.Query().Where(xx).FirstOrDefaultAsync();
2、新增:
1 _repository.Add(xx) or AddRange(xx);
2 _repository.SaveAsync();
3、删除:
1 _repository.Delete(xx);
2 _repository.SaveAsync();
4、更新:
1 实体对象.属性=new value;
2 _repository.SaveAsync();
5、事务:
1 using (var transaction = _repository.BeginTransaction())
2 {
3 ... ...
4 _repository.SaveChanges();
5 ... ...
6 _server.xxx();
7 transaction.Commit();
8 }
四、深知自己水平有限,写的不妥之处还望见谅。如本文对你有帮助,还请帮忙推荐支持一下,也欢迎院子各路大路批评指正,谢谢。
参考文章:
1、【.Net设计模式系列】仓储(Repository)模式 ( 一 )
2、 Repository模式
作者:Wade
出处:https://www.cnblogs.com/wader008/p/12979681.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
.Net Core之仓储(Repository)模式的更多相关文章
- 【.Net设计模式系列】仓储(Repository)模式 ( 一 )
开篇 2016新年伊始,望眼过去,不知不觉在博客园已经注册8个月啦,由于最近忙于工作,博客迟迟没有更新.直到最近一直研究.Net设计模式,对一些模式有所感悟,故拿出自己的心得与大家分享,在接下来的所有 ...
- Go 中 ORM 的 Repository(仓储)模式
ORM 在业务开发中一直扮演着亦正亦邪的角色.很多人赞颂 ORM,认为 ORM 与面向对象的契合度让代码简洁有道.但是不少人厌恶它,因为 ORM 隐藏了太多的细节,埋下了超多的隐患.在 Go 中,我们 ...
- Asp.Net Core + Dapper + Repository 模式 + TDD 学习笔记
0x00 前言 之前一直使用的是 EF ,做了一个简单的小项目后发现 EF 的表现并不是很好,就比如联表查询,因为现在的 EF Core 也没有啥好用的分析工具,所以也不知道该怎么写 Linq 生成出 ...
- 在Apworks数据服务中使用基于Entity Framework Core的仓储(Repository)实现
<在ASP.NET Core中使用Apworks快速开发数据服务>一文中,我介绍了如何使用Apworks框架的数据服务来快速构建用于查询和管理数据模型的RESTful API,通过该文的介 ...
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
项目开发中的一些注意事项以及技巧总结 1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...
- 基于EF Core的Code First模式的DotNetCore快速开发框架
前言 最近接了几个小单子,因为是小单子,项目规模都比较小,业务相对来说,也比较简单.所以在选择架构的时候,考虑到效率方面的因素,就采取了asp.net+entity framework中的code f ...
- C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入
C# 嵌入dll 在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...
- 关于MVC EF架构及Repository模式的一点心得
一直都想写博客,可惜真的太懒了或者对自己的描述水平不太自信,所以...一直都是不想写的状态,关于领域驱动的东西看了不少,但是由于自己水平太差加上工作中实在用不到,所以一直处于搁置状态,最近心血来潮突然 ...
- C#进阶系列——DDD领域驱动设计初探(二):仓储Repository(上)
前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原 ...
随机推荐
- JAVA_WEB--jsp语法
JSP声明 一个声明语句可以声明一个或多个变量.方法,供后面的Java代码使用.在JSP文件中,必须先声明这些变量和方法然后才能使用它们. JSP声明的语法格式: <%! declaration ...
- CodeForces - 1176A Divide it! (模拟+分类处理)
You are given an integer nn. You can perform any of the following operations with this number an arb ...
- 数学--数论--Hdu 5793 A Boring Question (打表+逆元)
There are an equation. ∑0≤k1,k2,⋯km≤n∏1⩽j<m(kj+1kj)%1000000007=? We define that (kj+1kj)=kj+1!kj! ...
- 图论--SCC强连通缩点--Tarjan
强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作. // Tarjan算法求有向图强连通分量并缩点 #include<iost ...
- LeetCode 56,57,60,连刷三题不费劲
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第34篇文章,刚好接下来的题目比较简单,很多和之前的做法类似.所以我们今天出一个合集,一口气做完接下来的57.5 ...
- B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路
B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...
- SQL SERVER 函数举例
需求说明 将字符串按照指定的分隔符进行分割,并将结果按照从后往前的顺序倒序排列,拼接后的结果用‘/’符连接.(也可以按照指定符号分割为多个列,修改最后一部分即可) 创建测试表及数据 /* 创建一张测试 ...
- webpack4使用出现ERROR in Template execution failed: ReferenceError: HtmlwebpackPlugin is not defined
问题描述 博主在使用webpack4的时候,使用了ejs文件,先附上ejs中的代码: <!doctype html> <html lang="zh-CN"> ...
- [hdu4710 Balls Rearrangement]分段统计
题意:求∑|i%a-i%b|,0≤i<n 思路:复杂度分析比较重要,不细想还真不知道这样一段段跳还真的挺快的=.= 令p=lcm(a,b),那么p就是|i%a-i%b|的循环节.考虑计算n的答案 ...
- Mysql 常用函数(1)- 常用函数汇总
Mysql常用函数的汇总,可看下面系列文章 Mysql常用函数有哪几类 数值型函数 字符串型函数 日期时间函数 聚合函数 流程控制函数 数值型函数 函数名称 作用 ABS 求绝对值 SQRT 求二次方 ...