Intern Day112 - .NET开发中对IRepository接口的理解
为什么要用Repository
总结出Repository的作用就是:在项目中把一些 常用&代码量较多的代码 封装 到 Repository
中,然后再用去访问,避免代码冗余、不优雅。
借用https://www.cnblogs.com/jake1/archive/2013/04/23/3039101.html中的一段文字,总结的很好:
-
仓储(Respository)是存在于工作单元和数据库之间单独分离出来的一层,是对数据访问的封装。优点如下:
-
业务层不需要知道它的具体实现,达到了分离关注点。
-
提高了对数据库访问的维护,对于仓储的改变并不会改变业务的逻辑,数据库可以用Sql Server,MySql等。
-
我们还可以利用
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