专栏首页.Net框架学苑Dapper.Common基于Dapper的开源LINQ超轻量扩展

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

  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

测试

映射

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; }
  }

配置

//在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
}

使用

1.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();
  }

原文地址:https://cnblogs.com/chaeyeon/p/11028480.html

扫码关注我们,我们学的不仅是框架,更是梦想!更多技术文章查看 http://letyouknow.net/

本文分享自微信公众号 - dotNet框架学苑(LetYouKnowNet),作者:花间岛

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Exceptionless - .Net Core开源日志框架

    今天要给大家介绍的Exceptionless是一个基于 .net core的开源日志框架,Exceptionless的意思是:没有异常。Exceptionles...

    .Net框架学苑
  • CentOS7 vsftp 安装与配置(视频教程)

    #①当chroot_list_enable=YES,chroot_local_user=YES时,在/etc/vsftpd.chroot_list文件中列出的用...

    .Net框架学苑
  • Ocelot(五)- 流量限制、服务质量

    本文是我关于Ocelot系列文章的第五篇,流量限制、服务质量。Ocelot允许针对具体的服务接口进行流量限制,以便下游服务不会过载而影响响应速度。服务质量则是O...

    .Net框架学苑
  • JavaScript 新手的踩坑日记

    在1995年5月,Eich 大神在10天内就写出了第一个脚本语言的版本,JavaScript 的第一个代号是 Mocha,Marc Andreesen 起的这个...

    一缕殇流化隐半边冰霜
  • iOS多边形马赛克的实现(上)

    马赛克(英语:Mosaic)是镶嵌艺术的音译,原本是指一种装饰艺术,通常使用许多小石块或有色玻璃碎片拼成图案,在教堂中的玻璃艺品,又称为花窗玻璃(stained...

    天天P图攻城狮
  • iOS多边形马赛克的实现(下)

    上一篇里我们详述了多边形马赛克的实现步骤,末尾提出了一个思考:如何在涂抹时让马赛克逐块显示呢? 再回顾一下多边形马赛克的实现。首先进行图片预处理,将原图转成bi...

    天天P图攻城狮
  • InnoDB Cluster详解

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    用户1148526
  • SpringBoot中导入Excel的总结

    3 页面我们使用Jquery的form表单上传 jquery.form.js 地址:https://github.com/jquery-form/form

    用户5927264
  • ASP.NET Core 2.0 MVC项目实战

    毕业后入职现在的公司快有一个月了,公司主要的产品用的是C/S架构,再加上自己现在还在学习维护很老的delphi项目,还是有很多不情愿的。之前实习...

    程序员宇说
  • 迭代器和快速失败机制

    对于array,我们直接用访问下标的方式对他进行遍历,因为我们知道他是一个数组,就像遍历一个链表用.next()进行遍历,因为我们知道.next()指向了下一个...

    naget

扫码关注云+社区

领取腾讯云代金券