zoukankan      html  css  js  c++  java
  • soul.extensions.entityframework增强efcore

    开发的初衷

      由于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();
  • 相关阅读:
    Rsync命令参数详解
    mysql 主从同步如何 把从数据的版本升级到指定的版本
    MySQL同步故障:" Slave_SQL_Running:No" 两种解决办法 (转)
    Linux VPS/服务器 网站及数据库自动本地备份并FTP上传备份脚本
    在kloxo中把不带www的域名做301到带www的域名
    mysql sorce 导入数据乱码问题解决
    linux后台运行和关闭SSH运行,查看后台任务
    centos下MySQL主从同步配置
    ecshop 无法上传产品图片 服务环境少了GD库
    EOJ2902 Contest
  • 原文地址:https://www.cnblogs.com/chaeyeon/p/14819091.html
Copyright © 2011-2022 走看看