Intern Day112 - .NET开发中对IRepository接口的理解

为什么要用Repository

总结出Repository的作用就是:在项目中把一些 常用&代码量较多的代码 封装Repository 中,然后再用去访问,避免代码冗余、不优雅。

借用https://www.cnblogs.com/jake1/archive/2013/04/23/3039101.html中的一段文字,总结的很好:

  • 仓储(Respository)是存在于工作单元和数据库之间单独分离出来的一层,是对数据访问的封装。优点如下:

    1. 业务层不需要知道它的具体实现,达到了分离关注点。

    2. 提高了对数据库访问的维护,对于仓储的改变并不会改变业务的逻辑,数据库可以用Sql Server,MySql等。

    3. 我们还可以利用 IRepository.cs 接口,对数据进行操作:比如执行命令、重载不同查询结果集合、查询实体、查询返回结果值等。

Repository在项目中的使用

本来我们访问数据库是这样的:

public void Test()
{
	 // 直接用 _unitofwork.DbContext.xxx去访问
	_unitofwork.DbContext.xxx.Skip(3).Take(2).ToList();
}

用了Repository后是这样的:

namespace xxx.xxx.xxx.Application.Services
{
    public class RoleService : IRoleService
    {
	 // Repository和UnitOfWork定义 和下面一一对应
          private readonly IUnitOfWork<xxxDbContext> _unitofwork; // 1
          private readonly IxxxPrincipal _principal; // 2
          private readonly IRepository<Study> _studyRepository; // 3
          private readonly IRepository<PeopleRole> _roleRepository; // 4

          public RoleService(IUnitOfWork<xxxDbContext> unitofwork, IxxxPrincipal principal)
          {
                _unitofwork = unitofwork; // 1
                _principal = principal; // 2
                _studyRepository = _unitofwork.GetRepository<Study>(); // 3
                _roleRepository = _unitofwork.GetRepository<PeopleRole>(); // 4
          }

          // 创建角色
          public async Task<CreateRoleOutput> CreateRole(CreateRoleInput input)
          {
                var study = await _studyRepository.FindAsync(input.StudyId);

                var role = new PeopleRole
                {
                      StudyId = input.StudyId
                };

                await _roleRepository.InsertAsync(role);

                await _unitofwork.SaveChangesAsync();

                return new CreateRoleOutput
                {
                      StudyId = role.StudyId,
                      Id = role.Id
                };
          }

          // 查询角色
          public async Task<RoleOutput> GetRole(GetRoleInput input)
          {
                var role = await _roleRepository.Query(x => x.Id == input.RoleId)
							 .Where(x => x.StudyId == input.StudyId)
							 .FirstAsync(); // LINQ+Lambda语法
                return new RoleOutput
                {

                      StudyId = role.StudyId,
                      Id = role.Id
                };
          }

          // …………

    }
}

EF和Repository等之间关系

关于EF、Repository、Factory、Service之间的关系详情代码可见:https://www.cnblogs.com/panpanwelcome/p/7357244.html

该文总结如下:

  • 实体Entities:具备唯一ID,能够被持久化,具备业务逻辑,对应现实世界业务对象。

  • 值对象Value objects:不具有唯一ID,由对象的属性描述,一般为内存中的临时对象,可以用来传递参数或对实体进行补充描述。

  • 工厂Factories:主要用来创建实体,目前架构实践中一般采用IOC容器来实现工厂的功能。

  • 仓库Repositories:用来管理实体的集合,封装持久化框架。

  • 服务Services:为上层建筑提供可操作的接口,负责对领域对象进行调度和封装,同时可以对外提供各种形式的服务。

Respository查询的性能问题

关于Respository查询的性能问题可以看下这个(但是一般用不到),具体可见该链接下讨论到的一些问题:https://q.cnblogs.com/q/70931

上一篇:spa项目开发之tab页实现


下一篇:解决Oracle+Mybatis批量插入报错:SQL 命令未正确结束