• Dapper.Common基于Dapper的开源LINQ超轻量扩展


    Dapper.Common

      Dapper.Common是基于Dapper的LINQ实现,支持.net core,遵循Linq语法规则、链式调用、配置简单、上手快,支持Mysql,Sqlserver(目前只实现了这两个数据库,实现其他数据库也很轻松),支持单表,多表,自定义函数等功能。源码及其简单,直白,解析Lambda只有300行左右代码。严格区分C#函数和数据库函数,你可以在表达式中调用C#函数(不推荐,推荐将计算结果保存到变量,在写入lambda表达式),性能损失在表达式编译:常量>变量>函数。损失多少可以通过ExpressionUtil.BuildExpression()来测试,几万次耗时百毫秒及别。

      开源地址:https://github.com/1448376744/Dapper.Common

      Nuget:Install-Package Dapper.Common -Version 1.5.0

    0.Test

    1.Mapper

      public class User
      {
           /// <summary>
    /// 如果表名与字段名一致,可以不用Column进行注解,主键采用类型的第一个属性【不推荐】
    /// name:用于映射字段名和数据库字段不一致【完全可以用T4一键生成我GitHub有现成的】 /// key: /// 目前实现了Primary的定义,设置为Primary的字段update实体时,默认采用该字段为更新条件 /// isIdentity: /// 设置未true时在Insert时不会向该字段设置任何值 /// isColumn: /// 标识该字段是否在数据库存在,用于扩展User而不在sql中生成该字段 /// </summary> [Column(name: "id", key: ColumnKey.Primary, isIdentity: true, isColumn: true)] public int? Id { get; set; } [Column(name:"nick_name")] public string NickName { get; set; } [Column(name: "create_time")] public DateTime? CreateTime { get; set; } }

    2.Config

    //在App启动时执行一次即可
    SessionFactory.AddDataSource(new DataSource()
    {
        Name = "mysql",
        Source = () => new SqlConnection("connectionString"),
        SourceType = DataSourceType.SQLSERVER,
        UseProxy = true//使用Session的静态代理实现,记录日志,执行耗时,线上环境建议关闭代理
    });
    //获取数据库上下文 using (var session = SessionFactory.GetSession("msql")) { //linq to sql }

    3.Insert

    var entity = new User()
    {
        CreateTime=DateTime.Now,
        NickName="dapper",
    };
    //绝大部分接口可以设置condition已决定是否执行,支持批量更新
    session.From<User>().Insert(entity,condition:1>2);
    //查看日志,如果出现异常,应该在catch里,查看session.Loggers
    var loggers = session.Loggers;

    2.Update

    var entity = new User()
    {
      Id=2,
      NickName="李四"
    };
    //更新所有字段(where id=2),支持批量,显然除NickName之外将被更新成null session.From<User>().Update(entity); //更新部分字段 session.From<User>() .Set(a => a.NickName, "李四", condition: true)//condition为true时更新该字段 .Set(a => a.Balance, a => a.Balance + 100)//余额在原来基础增加100 .Where(a => a.Id.In(1,2,3))//将id为1,2,3的记录进行更新 .Update();

    3.Delete

    //删除id>5||nick_name like '%da%'
     session.From<User>()
        .Where(a=>a.Id>5||a.NickName.Like("da"))
        .Delete();

    4.Single

      //查询全部字段
      var user1 = session.From<User>()
          .Where(a=>a.Id==2)
          .Single();
     
      //查询部分字段
      var user2 = session.From<User>()
         .Where(a => a.Id == 2)
         .Single(s=>new
         {
             s.Id,
             s.NickName
         });

    5.Select

     //查询:where id in(1,2,3)
     var list = session.From<User>()
            .Where(a => a.Id.In("1,2,3".Split(',')))
            .Select();

    6.Where

     //构建动态查询,condition: true执行,通过condition选择分支,多个where之间用 and 连接
     var list = session.From<User>()
            .Where(a => a.Id.In(1, 2, 3), condition: true)
            .Where(a => a.NickName.Like("da"), condition: false)
            .Where(a => a.Id > 2 || (a.NickName.Like("da") && a.Balance > 50))
            .Where("select * from user_bill where user_bill.user_id=user.id")//同样可以当作字符串拼接工具
            .Select();

    7.Function

     /// <summary>
     /// 自定义函数
     /// </summary>
     public static class MySqlFun
     {
         //这里使用泛型并不是必须的,只用函数名在数据库存在即可,泛型为了指定返回数据类型
         [Function]//Dapper.Common严格区分C#函数和数据库函数,一定要用该特性标识数据库函数
         public static T COUNT<T>(T column)
         {
             return default(T);
         }
         [Function]
         public static T MAX<T>(T column)
         {
             return default(T);
         }
         [Function]
         public static T DISTINCT<T>(T column)
         {
             return default(T);
         }
       [Function]
       public static T DATE<T>(T column)
    {
         return default(T);
       }
    }

    8.GroupBy

     var list = session.From<Order>()
         .GroupBy(a => a.UserId)//多个条件可以new一个匿名对象,也可以并联多个group
         .Having(a => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > 10)//count(distinct(user_id))>10
         .Select(s => new
         {
             s.UserId,
             OrderCount = MySqlFun.COUNT(1L),//这里应该返回long int,
             MaxFee = MySqlFun.MAX(s.TotalFee)
         });

    9.Join

     var list = session.From<Order, User>()
         .Join((a, b) => a.UserId == b.Id, JoinType.Inner)
         .GroupBy((a, b) => a.UserId)
         .Having((a, b) => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > 10)//count(distinct(user_id))>10
         .Select((a, b) => new
         {
             a.UserId,
             b.NickName,
             OrderCount = MySqlFun.COUNT(1L),//这里应该返回long int,
             MaxFee = MySqlFun.MAX(a.TotalFee)
         });

    10.SubQuery

    var list = session.From<Order>()
        .GroupBy(a  => a.UserId)
        .Having(a => MySqlFun.COUNT(MySqlFun.DISTINCT(a.UserId)) > 10)
        .Select(a => new
        {
            a.UserId,
            UserName=Convert.ToString("select nick_name from user where user.id=order.user_id"),//如果这个子查询返回的是int:Convert.ToInt32(sql)
            OrderCount = MySqlFun.COUNT(1L),//这里应该返回long int【这就是为什么定义成泛型函数】,
            MaxFee = MySqlFun.MAX(a.TotalFee)
        });

    11.Page

    //分页应该写在Where,Having,Group之后(如果有)
    var
    list = session.From<User>() .Where(a=>a.NickName != null) .Page(1,10,out long total) .Select();

    12.Take

    var list = session.From<User>()
            .Take(5)
            .Select();

    13.Skip

    //从数据库索引为1的位置(跳过1之前的记录),获取10
    var
    list = session.From<User>() .Skip(1,10) .Select();

    14.Sum

    var list= session.From<User>()
         .Sum(s=>s.Balance*s.Id);

    15.Exists

    //内部采用exist子查询判断满足where条件的记录是否存在
    var
    flag = seesion.From<User>() .Where(a=>a.Id > 10) .Exists();

    16.OrderBy

    var list1 = session.From<User>()
        .Order(a=>a.Id)
        .Select();
    
    var list2 = session.From<User>()
        .GroupBy(a => MysqlFun.DATE(a.CreateTime))
        .OrderByDescending(a => MysqlFun.DATE(a.CreateTime))
        .Select(s=>new 
        {
             Date=MysqlFun.DATE(s.CreateTime),
             Count = MysqlFun.Count(1L)
        });

    17.Filter

    var user =new User ()
    {
      Id = 12   Balance
    = 50,   NickName = "张三",   CreateTime = Datetime.Now }; //Filter会在Insert,Update,Select,过滤掉不想要的字段
    //这将不会更新余额及创建时间
    var row = session.From<User>() .Filter(f=>new { f.CreateTime, f.Balance, }) .Update(user);

     18.Transaction

      //获取数据库上下文
      ISession session = null;
      try
      {
        session=SessionFactory.GetSession();
    //开启事务 session.Open(true); //sql //提交事务 session.Commit(); } catch (Exception) { session?.Rollback(); throw; } finally { session?.Close(); }

     19.Custom Page

    //该策略可适用于百万级别,单表条件查询
    //思想:先只查满足条件的id,并分页,然后where in (idArray)查详情
    //还有一种超高性能的分页思想:每一页更具上一页最大id开始向下分页查询,同样可以集成到这一个方法里(加个分页类型参数)
    public static Dapper.Extension.IQueryable<T> SPage<T>(this Dapper.Extension.IQueryable<T> queryable, int index, int count, out long total) where T : class, new() { total = 0; if (index <= 90000) { //采用limit queryable.Page(index, count, out total); } //对mysql进行扩展 else if (queryable is MysqlQuery<T> mysqlQuery) { total = queryable.Count(); var table = EntityUtil.GetTable<T>(); var idName = table.Columns.Find(f => f.ColumnKey == ColumnKey.Primary).ColumnName; //先只查询主键字段并分页 var where = mysqlQuery._whereBuffer.Length > 0 ? "where " + mysqlQuery._whereBuffer : ""; var orderby = mysqlQuery._orderBuffer.Length > 0 ? "order by" + mysqlQuery._orderBuffer : ""; var sql = string.Format("select {0} from {1} {2} {3} limit {4},{5}", idName, table.TableName, where, orderby, (index - 1) * count, count); var idArray = mysqlQuery._session.Query<long>(sql, mysqlQuery._param); //重置 mysqlQuery._whereBuffer.Clear(); //新建条件 if (idArray.Count() > 0) { queryable.Where(string.Format("{0} in @idArray", idName), p => p.Add("@idArray", idArray)); } } return queryable; } var row = Session.From<Member>() .SPage(2,2,out long total) .Select();
  • 相关阅读:
    20172322 《程序设计与数据结构》第六周学习总结
    20172322 2018-2019-1 10月19日课上测试报告
    20172322 《程序设计与数据结构》第五周学习总结
    20172322 《程序设计与数据结构》第四周学习总结
    172322 2018-2019-1 《Java软件结构与数据结构》实验一报告
    20172322 《程序设计与数据结构》第三周学习总结
    20172322 《程序设计与数据结构》第二周学习总结
    20172303 20172322 2017-2018-2 暑假作业 结对编程项目-舒尔特方格(增补:计时器的加入与页面优化)
    20172322 《程序设计与数据结构》第一周学习总结
    20172322 2017-2018-2《程序设计与数据结构》(上)课程总结
  • 原文地址:https://www.cnblogs.com/chaeyeon/p/11028480.html
Copyright © 2020-2023  润新知