Skip to content
aps.net core ef and dapper
C# TSQL
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
example add code Oct 9, 2019
sqlscript add code Oct 9, 2019
src/Leo.Chimp 发包版本 Sep 29, 2019
test/Leo.Chimp.Test 修改部分命名空间 Oct 9, 2019
.gitattributes 添加 .gitignore 和 .gitattributes。 Sep 29, 2019
.gitignore 添加 .gitignore 和 .gitattributes。 Sep 29, 2019
Leo.Chimp.sln add code Oct 9, 2019
README.MD add code Oct 9, 2019
README.md 包版本 Sep 29, 2019

README.MD

背景

17年开始,公司开始向DotNet Core转型,面对ORM工具的选型,当时围绕Dapper和EF发生了激烈的讨论。项目团队更加关注快速交付,他们主张使用EF这种能快速开发的ORM工具;而在线业务团队对性能有更高的要求,他们更希望使用能直接执行Sql语句的Dapper,这样可控性更高。而对于架构团队来说,满足开发团队的各种需求,提高他们的开发效率是最核心的价值所在,所以当时决定做一个混合型的既支持EF又支持dapper的数据仓储。

为什么选择EF+Dapper

目前来说EF和Dapper是.NET平台最主流的ORM工具,团队成员的接受程度很高,相关的资料非常齐全,学习成本很低,各种坑也最少。

介绍

  1. 它不是一个ORM工具,它不做任何关于数据底层的操作
  2. 它是一个简易封装的数据库仓储和工作单元模型
  3. 能帮助你快速的构建项目的数据访问层
  4. 经过了2年多时间,10个项目组,大小近100多个线上项目的考验
  5. 支持EF和Dapper,可以在项目中随意切换使用
  6. 支持工作单元模式,也支持传统事务
  7. 支持Mysql和Mssql
  8. 支持同步和异步操作,推荐使用异步

PS: 简单操作使用EF,复杂sql操作使用Dapper是快速开发的秘诀。

使用方法

引入nuget

<PackageReference Include="Leo.Chimp" Version="2.1.2" />

创建实体对象,继承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地址

You can’t perform that action at this time.