开发的初衷
由于ef提供的api主要是基于实体操作,如果我们想根据一个指定条件去更新实体和删除实体,势必存在性能问题。习惯了linq在去手写sql显然内心是拒绝和绝望的!!!
已经开发好基本的api并在github开源,开发是面向所有orm的,你只需要实现IMetadataProvider这个接口就可以将linq移植到类似dapper这种orm上面,语法风格部分借鉴sqlsugar,这里欢迎大家一起。
加入完善。
开源地址
1448376744/Soul.Extensions.EntityFrameworkCore: Soul.Extensions.EntityFrameworkCore (github.com)
使用方式
1. 继承
public class MyDbContext : SoulDbContext { }
2. 实现接口
public class SoulDbContext : DbContext, ISoulDbContext { public IDbContextBehavior SoulContextBehavior { get; } = new DbContextBehavior(); public IMetadataProvider MetadataProvider { get; private set; } public SoulDbContext() { MetadataProvider = new EntityFrameworkMetadataProvider(Model,Database.ProviderName); } public SoulDbContext(IDbContextBehavior contextBehavior) { SoulContextBehavior = contextBehavior; MetadataProvider = new EntityFrameworkMetadataProvider(Model, Database.ProviderName); } public SoulDbContext(DbContextOptions options) : base(options) { MetadataProvider = new EntityFrameworkMetadataProvider(Model, Database.ProviderName); } public SoulDbContext(DbContextOptions options, IDbContextBehavior contextBehavior) : base(options) { SoulContextBehavior = contextBehavior; MetadataProvider = new EntityFrameworkMetadataProvider(Model, Database.ProviderName); } }
原生sql支持
var row = context.Execuet("delete from student id = 1"); //支持类似dapper的参数格式,具体查看源码 var list = context.Query<Student>("select * from student where Id = @Id",new {Id = 1});
基于命令更新
1. insert
//有这个api就不需要使用AutoMapper了 var dto = new {Age = 3}; context.Insert<Student>(dto) .Execute(); //设置默认值 context.Insertable<Student>(new {Age = 3}) .Initialize(c=> { //有了这个就可以设置一些不用在swagger显示的值了 c.Add(nameof(Studen.CreateTime),DateTime.Now); }) .Execute();
2. update
var context = new DbContext(); context.Updateable<Student>() .Set(a=>a.Name,"zs") .Set(a=>a.Age,a=>a.Age+1) .Where(a=>a.Id>1) .Execute(); context.Updateable<Student>(new {Age = 3}) .Initialize(c=> { //有了这个就可以设置一些不用在swagger显示的值了 c.Add(nameof(Studen.Id),_identityServer.Id); }) .Execute();
3. delete
context.Deleteable<Student>() .Where(a=>a.Id>1) .Execute();
扩展查询
1. 基本结构
//基本结构 var data = await context.Queryable<Student>() .Where(a => a.Id > 0) .GroupBy(a => a.Name) .Having(a => SqlFun.Count(a.Id) > 1) .Select(s => new { s.Name, Count= SqlFun.Count(s.Id), }) .SingleOrDefaultAsync();
2. 调用函数
var sum = awiat context.Queryable<Student>() .Select(s=>SqlFun.SUM(s.Age)) .SingleOrDefaultAsync();
3. 计数查询
var count = context.Queryable<Student>() .Count();
4. 带有表达式的函数
var list = awiat context.Queryable<Student>() .Select(s=>SqlFun.SUM(SqlFun.IF(a.Gender>0,s.Age,0))) .ToListAsync();
5. casewhen
//case var list = context.Queryable<Student>() .Where(a => a.Id > 401) .Select(s => new { ShowGender = SqlFun.Case<int>( new { When = s.Gender = 0, Then = "男" }, new { When = s.Gender = 1, Then = "女" }, new { Else = "其他" }) }) .ToList();
6. 多表连接查询
var list = context.Queryable<Student,School>((a, b) => new JoinExpression(JoinType.Inner, a.SchoolId==b.Id)) .Select((a, b)=new { a.Id a.Name b.SchoolName }) .ToList();
自定义函数
[Function] public class SqlFun { //case when [CaseWhen] public static TSource Case<TSource>(params object[] expressions) { throw new NotImplementedException(); } //重命名 [Function("FIND_IN_SET")] public static int IndexOf(int s1,int s2) { //该函数并不会被执行 throw new NotImplementedException(); } public static TSource SUM<TSource>(TSource source) { //该函数并不会被执行 throw new NotImplementedException(); } public static TSource IF<TSource>(object expression,TSource source1,TSource source2) { //该函数并不会被执行 throw new NotImplementedException(); } } //使用 context.From<Student>() .Where(a=>SqlFunc.IndexOf('2',a.Name)>0) .Delete();