Skip to content

Commit

Permalink
add code
Browse files Browse the repository at this point in the history
  • Loading branch information
longxianghui committed Sep 29, 2019
1 parent cf8fd09 commit cdb962e
Show file tree
Hide file tree
Showing 24 changed files with 651 additions and 65 deletions.
24 changes: 24 additions & 0 deletions Leo.Chimp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leo.Chimp", "src\Leo.Chimp\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leo.Chimp.Test", "src\Leo.Chimp.Test\Leo.Chimp.Test.csproj", "{1CF7DFC0-5C7A-4E9C-B5A8-0C9609004F23}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Leo.Chimp.Example", "src\Leo.Chimp.Example\Leo.Chimp.Example.csproj", "{E911F809-ED33-491F-896D-341EF249303D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Leo.Chimp.Domain", "src\Leo.Chimp.Domain\Leo.Chimp.Domain.csproj", "{A1C15DD9-B856-472D-B0DA-BC69750C8736}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A9856CFD-8B10-4C9E-B4B7-E49704894C71}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{8DC16EBA-2D9F-473A-820E-5A96C35E44F5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "example", "example", "{98E27906-6784-4538-9CDA-90FDEA7C83EF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,10 +31,24 @@ Global
{1CF7DFC0-5C7A-4E9C-B5A8-0C9609004F23}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CF7DFC0-5C7A-4E9C-B5A8-0C9609004F23}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CF7DFC0-5C7A-4E9C-B5A8-0C9609004F23}.Release|Any CPU.Build.0 = Release|Any CPU
{E911F809-ED33-491F-896D-341EF249303D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E911F809-ED33-491F-896D-341EF249303D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E911F809-ED33-491F-896D-341EF249303D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E911F809-ED33-491F-896D-341EF249303D}.Release|Any CPU.Build.0 = Release|Any CPU
{A1C15DD9-B856-472D-B0DA-BC69750C8736}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1C15DD9-B856-472D-B0DA-BC69750C8736}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1C15DD9-B856-472D-B0DA-BC69750C8736}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1C15DD9-B856-472D-B0DA-BC69750C8736}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{AE57FE9E-110F-4BBD-AF58-243A37E334C3} = {A9856CFD-8B10-4C9E-B4B7-E49704894C71}
{1CF7DFC0-5C7A-4E9C-B5A8-0C9609004F23} = {8DC16EBA-2D9F-473A-820E-5A96C35E44F5}
{E911F809-ED33-491F-896D-341EF249303D} = {98E27906-6784-4538-9CDA-90FDEA7C83EF}
{A1C15DD9-B856-472D-B0DA-BC69750C8736} = {98E27906-6784-4538-9CDA-90FDEA7C83EF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D936E593-6A06-4989-8708-382308D741CF}
EndGlobalSection
Expand Down
211 changes: 211 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
#### 背景
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
```
```
创建实体对象,继承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 KingDbContext : BaseDbContext
{
public KingDbContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//your code
}
}
```
注入服务
```
services.AddKing<KingDbContext>(
opt =>
opt.UseSqlServer("Server=10.0.0.99;Database=king;Uid=sa;Pwd=Fuluerp123")
);
```
如果你没有创建上下文
```
services.AddKing(
opt =>
opt.UseSqlServer("Server=10.0.0.99;Database=king;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);
_unitOfWork.SaveChanges();
```
```
//sql语句新增
_unitOfWork.ExecuteAsync("insert school(id,name) values(@Id,@Name)",
school);
```
编辑
```
//编辑,支持批量编辑
var school = _schoolRepository.GetByIdAsync(Id);
school.Name="newschool";
_schoolRepository.Update(school);
_unitOfWork.SaveChanges();
```
```
//编辑,不用先查询
var school = new School
{
Id = "xxxxxx",
Name = "newschool"
};
_schoolRepository.Update(school, x => x.Name);
_unitOfWork.SaveChanges();
```
```
//sql语句编辑
_unitOfWork.ExecuteAsync("update school set name=@Name where id=@Id",
school);
```
删除
```
//删除,支持批量删除
_schoolRepository.Delete(school);
_unitOfWork.SaveChanges();
```
```
//根据lambda删除
_schoolRepository.Delete(x => x.Id == Id);
_unitOfWork.SaveChanges();
```
事务
```
//工作单元模式使用事务
await _schoolRepository.InsertAsync(school1);
await _schoolRepository.InsertAsync(school1);
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扩展的方法
_unitOfWork.GetConnection().QueryAsync("select * from school");
```
#### 写在最后
Chimp核心是基于EF和Dapper的,所以EF和Dapper一切功能都可以使用。比如导航属性,字段映射等等。这个库是线上项目核心依赖,会长期更新维护,希望大家能提出更好的意见。
#### 项目地址
[github地址](https://github.com/longxianghui/chimp.git)
19 changes: 19 additions & 0 deletions src/Leo.Chimp.Domain/Entities/School.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Leo.Chimp.Domain.Entities
{
public class School
{
public School()
{
Students = new List<Student>();
}

public Guid Id { get; set; }
public string Name { get; set; }

public List<Student> Students { get; set; }
}
}
17 changes: 17 additions & 0 deletions src/Leo.Chimp.Domain/Entities/Student.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace Leo.Chimp.Domain.Entities
{
public class Student : IEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid SchoolId { get; set; }
public DateTime Birthday { get; set; }

public School MySchool { get; set; }
}
}
19 changes: 19 additions & 0 deletions src/Leo.Chimp.Domain/KingDbContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;

namespace Leo.Chimp.Domain
{
public class KingDbContext : BaseDbContext
{
public KingDbContext(DbContextOptions options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//your code
}
}
}
11 changes: 11 additions & 0 deletions src/Leo.Chimp.Domain/Leo.Chimp.Domain.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Leo.Chimp\Leo.Chimp.csproj" />
</ItemGroup>

</Project>
18 changes: 18 additions & 0 deletions src/Leo.Chimp.Domain/Repositories/SchoolRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using Leo.Chimp.Domain.Entities;
using Microsoft.EntityFrameworkCore;

namespace Leo.Chimp.Domain.Repositories
{
public class SchoolRepository: EfCoreRepository<School>,ISchoolRepository
{
public SchoolRepository(DbContext context) : base(context)
{
}
}
public interface ISchoolRepository : IRepository<School>
{
}
}
20 changes: 20 additions & 0 deletions src/Leo.Chimp.Domain/Repositories/StudentRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
using Leo.Chimp.Domain.Entities;
using Microsoft.EntityFrameworkCore;

namespace Leo.Chimp.Domain.Repositories
{
public class StudentRepository: EfCoreRepository<Student>,IStudentRepository
{
public StudentRepository(DbContext context) : base(context)
{
}
}

public interface IStudentRepository : IRepository<Student>
{

}
}
28 changes: 28 additions & 0 deletions src/Leo.Chimp.Example/Controllers/ValuesController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Leo.Chimp.Domain.Repositories;
using Microsoft.AspNetCore.Mvc;

namespace Leo.Chimp.Example.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly ISchoolRepository _schoolRepository;
private readonly IUnitOfWork _unitOfWork;
public ValuesController(ISchoolRepository schoolRepository, IUnitOfWork unitOfWork)
{
_schoolRepository = schoolRepository;
_unitOfWork = unitOfWork;
}
[HttpGet]
public async Task<IActionResult> Get()
{
var schools = await _schoolRepository.TableNoTracking.ToPagedListAsync(1, 10);
return Ok(schools);
}
}
}
Loading

0 comments on commit cdb962e

Please sign in to comment.