我们经常在项目中使用仓储(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

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

05-13 16:16