我们经常在项目中使用仓储(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)模式的更多相关文章

  1. 【.Net设计模式系列】仓储(Repository)模式 ( 一 )

    开篇 2016新年伊始,望眼过去,不知不觉在博客园已经注册8个月啦,由于最近忙于工作,博客迟迟没有更新.直到最近一直研究.Net设计模式,对一些模式有所感悟,故拿出自己的心得与大家分享,在接下来的所有 ...

  2. Go 中 ORM 的 Repository(仓储)模式

    ORM 在业务开发中一直扮演着亦正亦邪的角色.很多人赞颂 ORM,认为 ORM 与面向对象的契合度让代码简洁有道.但是不少人厌恶它,因为 ORM 隐藏了太多的细节,埋下了超多的隐患.在 Go 中,我们 ...

  3. Asp.Net Core + Dapper + Repository 模式 + TDD 学习笔记

    0x00 前言 之前一直使用的是 EF ,做了一个简单的小项目后发现 EF 的表现并不是很好,就比如联表查询,因为现在的 EF Core 也没有啥好用的分析工具,所以也不知道该怎么写 Linq 生成出 ...

  4. 在Apworks数据服务中使用基于Entity Framework Core的仓储(Repository)实现

    <在ASP.NET Core中使用Apworks快速开发数据服务>一文中,我介绍了如何使用Apworks框架的数据服务来快速构建用于查询和管理数据模型的RESTful API,通过该文的介 ...

  5. 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获

    项目开发中的一些注意事项以及技巧总结   1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...

  6. 基于EF Core的Code First模式的DotNetCore快速开发框架

    前言 最近接了几个小单子,因为是小单子,项目规模都比较小,业务相对来说,也比较简单.所以在选择架构的时候,考虑到效率方面的因素,就采取了asp.net+entity framework中的code f ...

  7. 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,这种形 ...

  8. 关于MVC EF架构及Repository模式的一点心得

    一直都想写博客,可惜真的太懒了或者对自己的描述水平不太自信,所以...一直都是不想写的状态,关于领域驱动的东西看了不少,但是由于自己水平太差加上工作中实在用不到,所以一直处于搁置状态,最近心血来潮突然 ...

  9. C#进阶系列——DDD领域驱动设计初探(二):仓储Repository(上)

    前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原 ...

随机推荐

  1. VUE 后台管理系统权限控制

    谈一谈VUE 后台管理系统权限控制 前端权限从本质上来讲, 就是控制视图层的展示,比如说是某个页面或者某个按钮,后端权限可以控制某个用户是否能够查询数据, 是否能够修改数据等操作,后端权限大部分是基于 ...

  2. weak_ptr

    #include <iostream> #include <memory> using namespace std; int main(int argc, char **arg ...

  3. OSG程序设计之Hello World 4.0

    代码如下: //需要添加两个库:osgUtild.lib.osgTextd.lib #include <osgDB/ReadFile> #include <osgUtil/Optim ...

  4. Java——TCP/IP超详细总结

    网络的基础知识 一.协议 1.简介: 在计算机网络与信息通信领域里,人们经常提及“协议”一词.互联网中常用的具有代表性的协议有IP.TCP.HTTP等.而LAN(局域网)中常用的协议有IPX/SPX” ...

  5. 使用jQuery完成课工场论坛列表

    1.点击我要发帖 2.显示出form表单,然后我们填入标题和选择板块 3.点击发布,隐藏表单,发帖列表中出现随机头像,刚才填入的标题和板块显示在列表中,其中还显示出了发布消息的时间 4.再一次的点击我 ...

  6. C. Barcode dp

    https://codeforces.com/problemset/problem/225/C 这个题目和之前一个题目很像 https://www.cnblogs.com/EchoZQN/p/1090 ...

  7. 字节码编程,Javassist篇二《定义属性以及创建方法时多种入参和出参类型的使用》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一篇 Helloworld 中,我们初步尝试使用了 Javassist字节编程的 ...

  8. MATLAB与三大变换

    运行 Simulink 有三种方式: z 在 MATLAB 的命令窗口直接键入“Simulink”并回车: z 单击 MATLAB 工具条上的 Simulink 图标: z 在 MATLAB 菜单上选 ...

  9. 缓冲 buffer 和缓存 cache 的区别

    缓存(cache)是在读取硬盘中的数据时,把最常用的数据保存在内存的缓存区中,再次读取该数据时,就不去硬盘中读取了,而在缓存中读取. 缓冲(buffer)是在向硬盘写入数据时,先把数据放入缓冲区,然后 ...

  10. 省市县三级联动sql文件

    截止于2018年,中国有34个省级, 地级行政区划单位334个 县级行政区划单位2851个 乡级行政区划单位39888个 例如 湖南省有多少个市级单位: 先拿到湖南省的code,再查city表: SE ...