背景
17 年开始, 公司开始向 DotNet Core 转型, 面对 ORM 工具的选型, 当时围绕 Dapper 和 EF 发生了激烈的讨论. 项目团队更加关注快速交付, 他们主张使用 EF 这种能快速开发的 ORM 工具; 而在线业务团队对性能有更高的要求, 他们更希望使用能直接执行 Sql 语句的 Dapper, 这样可控性更高. 而对于架构团队来说, 满足开发团队的各种需求, 提高他们的开发效率是最核心的价值所在, 所以当时决定做一个混合型的既支持 EF 又支持 dapper 的数据仓储.
为什么选择 EF+Dapper
目前来说 EF 和 Dapper 是. NET 平台最主流的 ORM 工具, 团队成员的接受程度很高, 相关的资料非常齐全, 学习成本很低, 各种坑也最少.
介绍
它不是一个 ORM 工具, 它不做任何关于数据底层的操作
它是一个简易封装的数据库仓储和工作单元模型
能帮助你快速的构建项目的数据访问层
经过了 2 年多时间, 10 个项目组, 大小近 100 多个线上项目的考验
支持 EF 和 Dapper, 可以在项目中随意切换使用
支持工作单元模式, 也支持传统事务
支持 MySQL 和 Mssql
支持同步和异步操作, 推荐使用异步
PS: 简单操作使用 EF, 复杂 sql 操作使用 Dapper 是快速开发的秘诀.
使用方法
引入 nuget
<PackageReference Include="Leo.Chimp" Version="2.1.1" />
创建实体对象, 继承 IEntity
- public class School : IEntity
- {
- public Guid Id { get; set; }
- public string Name { get; set; }
- }
创建仓储接口和实现类, 分别继承 IRepository 和 EfCoreRepository
- public interface ISchoolRepository : IRepository<School>
- {
- }
- public class SchoolRepository: EfCoreRepository<School>,ISchoolRepository
- {
- public SchoolRepository(DbContext context) : base(context)
- {
- }
- }
创建上下文, 继承 BaseDbContext, 如果你不需要操作上下文可以不用做这一步
- public class ChimpDbContext : BaseDbContext
- {
- public ChimpDbContext(DbContextOptions options) : base(options)
- {
- }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- base.OnModelCreating(modelBuilder);
- //your code
- }
- }
注入服务
- services.AddChimp<ChimpDbContext>(
- opt =>
- opt.UseSqlServer("Server=10.0.0.99;Database=chimp;Uid=sa;Pwd=Fuluerp123")
- );
如果你没有创建上下文
- services.AddChimp(
- opt =>
- opt.UseSqlServer("Server=10.0.0.99;Database=chimp;Uid=sa;Pwd=Fuluerp123")
- );
在 Controller 中使用
- public class ValuesController : ControllerBase
- {
- private readonly ISchoolRepository _schoolRepository;
- private readonly IUnitOfWork _unitOfWork;
- public ValuesController(ISchoolRepository schoolRepository, IUnitOfWork unitOfWork)
- {
- _schoolRepository = schoolRepository;
- _unitOfWork = unitOfWork;
- }
- }
详细使用说明
查询
- // 根据主键查询
- _schoolRepository.GetById(Id)
- // 不带追踪的查询, 返回数据不能用于更新或删除操作, 性能快
- schoolRepository.TableNoTracking.First(x => x.Id == Id);
- // 带追踪的查询, 返回数据可以用于更新或删除操作, 性能稍慢
- schoolRepository.Table.First(x => x.Id == Id);
- // 分页查询
- _schoolRepository.TableNoTracking.ToPagedList(1,10);
- //sql 语句查询
- _unitOfWork.QueryAsync<School>("select * from school");
- //sql 分页查询
- _unitOfWork.QueryPagedListAsync<School>(1, 10, "select * from school order by id");
关于查询, 暴露了返回 IQueryable 的 TableNoTracking,Table 这两个属性, 让开发人员自己组装 Lambda 表达式进行查询操作
新增
- // 新增, 支持批量新增
- _schoolRepository.Insert(school);
- await _unitOfWork.SaveChangesAsync();
- //sql 语句新增
- await _unitOfWork.ExecuteAsync("insert school(id,name) values(@Id,@Name)",school);
- await _unitOfWork.SaveChangesAsync();
编辑
- // 编辑, 支持批量编辑
- var school = await _schoolRepository.GetByIdAsync(Id);
- school.Name="newschool";
- _schoolRepository.Update(school);
- await _unitOfWork.SaveChangesAsync();
- // 编辑, 不用先查询
- var school = new School
- {
- Id = "xxxxxx",
- Name = "newschool"
- };
- _schoolRepository.Update(school, x => x.Name);
- await _unitOfWork.SaveChangesAsync();
- //sql 语句编辑
- await _unitOfWork.ExecuteAsync("update school set name=@Name where id=@Id",school);
- await _unitOfWork.SaveChangesAsync();
删除
- // 删除, 支持批量删除
- _schoolRepository.Delete(school);
- await _unitOfWork.SaveChangesAsync();
- // 根据 lambda 删除
- _schoolRepository.Delete(x => x.Id == Id);
- await _unitOfWork.SaveChangesAsync();
事务
- // 工作单元模式使用事务
- await _schoolRepository.InsertAsync(school1);
- await _schoolRepository.InsertAsync(school2);
- await _unitOfWork.SaveChangesAsync();
- //dapper 使用事务
- using (var tran = _unitOfWork.BeginTransaction())
- {
- try
- {
- await _unitOfWork.ExecuteAsync("insert school(id,name) values(@Id,@Name)",
- school1,tran);
- await _unitOfWork.ExecuteAsync("insert school(id,name) values(@Id,@Name)",
- school2,tran);
- tran.Commit();
- }
- catch (Exception e)
- {
- tran.Rollback();
- }
- }
- //dapper+ef 混合使用事务
- using (var tran = _unitOfWork.BeginTransaction())
- {
- try
- {
- await _schoolRepository.InsertAsync(school1);
- await _unitOfWork.SaveChangesAsync();
- await _unitOfWork.ExecuteAsync("insert school(id,name) values(@Id,@Name)",
- school2);
- tran.Commit();
- }
- catch (Exception e)
- {
- tran.Rollback();
- }
- }
高级用法
- // 通过 GetConnection 可以使用更多 dapper 扩展的方法
- await _unitOfWork.GetConnection().QueryAsync("select * from school");
写在最后
Chimp 核心是基于 EF 和 Dapper 的, 所以 EF 和 Dapper 的功能都可以使用. 比如导航属性, 字段映射等等. 这个库是线上项目核心依赖, 会长期更新维护, 希望大家能提出更好的意见.
QQ 群: 687800650 有问题可以加群交流
项目地址
数据库脚本在根目录的 sqlscript 文件夹里面
GitHub 地址 https://github.com/longxianghui/chimp.git
来源: https://www.cnblogs.com/longxianghui/p/11635928.html