.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类怎样使用仓储类实现对单一实体的各种操作。

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模式

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章