背景

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.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);

编辑

//编辑,支持批量编辑
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);

删除

//删除,支持批量删除
_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地址

同时支持EF+Dapper的混合仓储,助你快速搭建数据访问层的更多相关文章

  1. 【原创】打造基于Dapper的数据访问层

    [原创]打造基于Dapper的数据访问层   前言 闲来无事,花几天功夫将之前项目里用到的一个数据访问层整理了出来.实现单个实体的增删改查,可执行存储过程,可输出返回参数,查询结果集可根据实际情况返回 ...

  2. MVC+Ef项目(2) 如何更改项目的生成顺序;数据库访问层Repository仓储层的实现

    我们现在先来看看数据库的生成顺序   居然是 Idal层排在第一,而 web层在第二,model层反而在第三 了   我们需要把 coomon 公用层放在第一,Model层放在第二,接下来是 Idal ...

  3. webapi框架搭建-数据访问ef code first

    webapi框架搭建系列博客 为什么用ef? 我相信很多博友和我一样都有这种“选择困难症”,我曾经有,现在也有,这是技术人的一个通病——总想用“更完美”的方式去实现,导致在技术选择上犹豫不决,或总是推 ...

  4. 自己写的Dapper通用数据访问层

    using Microsoft.Practices.EnterpriseLibrary.Data; using Microsoft.Practices.EnterpriseLibrary.Data.O ...

  5. MVC+EF 理解和实现仓储模式和工作单元模式

    MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generi ...

  6. .Net Core中使用Dapper构建泛型仓储

    前言:Dapper是.NET的简单对象映射器,在速度方面拥有ORM之王的称号,与使用原始ADO.NET读取数据一样快.ORM是对象关系映射器,它负责数据库和编程语言之间的映射. 仓储主要是用来解耦业务 ...

  7. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(2)-数据库访问层的设计Demo ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1)框架搭建 前言:这 ...

  8. Asp.net Core 3.1 引用ORM工具包 yrjw.ORM.Chimp(EF + dapper + Autofac)使用教程

    yrjw.ORM.Chimp 介绍 It is not the encapsulation of ORM,a based on EF + dapper + Autofac, is repository ...

  9. MySQL官方.NET Core驱动已出,支持EF Core

    千呼万唤始出来MySQL官方.NET Core驱动已出,支持EF Core. 昨天MySQL官方已经发布了.NET Core 驱动,目前还是预览版,不过功能已经可用. NuGet 地址:https:/ ...

随机推荐

  1. Oracle误操作--被提交后的数据回退(闪回)

    由于一时的粗心,在做update操作时,忘记了加where条件,导致全表数据被修改.此类错误实属不该!!特此记录一下!! 网上搜索Oracle数据回退操作,介绍如下: 闪回级别 闪回场景 闪回技术 对 ...

  2. 牛客OI测试赛 C 序列 思维

    链接:https://www.nowcoder.com/acm/contest/181/C来源:牛客网 题目描述 小a有n个数,他想把他们划分为连续的权值相等的k段,但他不知道这是否可行. 每个数都必 ...

  3. lightoj 1145 - Dice (I)(dp+空间优化+前缀和)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1145 题解:首先只要是dp的值只和上一个状态有关系那么就可以优化一维,然后这题 ...

  4. CF1005D Polycarp and Div 3 思维

    Polycarp and Div 3 time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  5. unicode编码原理及问题

    历史在1963年,计算机的使用尚不广泛,那时使用的是7-bit的ASCII码,范围为0-127作为字符的编码,只支持少部分的字符,但是随着计算机的普及,不同的国家地区开始自己制造自己的编码规范,这导致 ...

  6. 【Offer】[5] 【替换空格】

    题目描述 思路分析 Java代码 代码链接 题目描述 请实现一个函数,把字符串中的每个空格替换成"%20". 例如输入"We are happy.",则输出&q ...

  7. SpringBoot+SpringMVC+MyBatis快速整合搭建

    作为开发人员,大家都知道,SpringBoot是基于Spring4.0设计的,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程.另外Spr ...

  8. Storm 系列(六)—— Storm 项目三种打包方式对比分析

    一.简介 在将 Storm Topology 提交到服务器集群运行时,需要先将项目进行打包.本文主要对比分析各种打包方式,并将打包过程中需要注意的事项进行说明.主要打包方式有以下三种: 第一种:不加任 ...

  9. 学习笔记-Unity3d代码实现Windows10加载圈圈的效果

    最近在写一个Unity3d的模仿windows10的桌面的程序,由于Unity3d本身不支持Gif图片,所以突发奇想使用代码来实现接近的. 接下来是代码部分:不一一解析,很简单,看的懂原理就Okly了 ...

  10. 关于Java网络编程

    一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...