我們經常在項目中使用倉儲(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
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。