DMOZ中文网站分类目录-免费收录各类优秀网站的中文网站目录.
  • DmozDir.org
DMOZ目录快速登录入口-免费收录各类优秀网站的中文网站目录.由人工编辑,并提供网站分类目录检索及地区分类目录检索,是站长免费推广网站的有力平台!

献给 Dapper 使用者的一份礼物

  • 献给 Dapper 使用者的一份礼物

  • 已被浏览: 32 次2020年12月07日    来源:  https://www.cnblogs.com/kellynic/p/14095502.html
  • FreeSql CSRedis为 .NET 开源事业添砖加瓦,https://github.com/2881099写在开头众所周知 Dapper 是 .NET 下最轻最快的 orM,它是喜欢写 SQL 码农的福音,相对于 SqlHelper

    写在开头

    众所周知 Dapper 是 .NET 下最轻最快的 ORM,它是喜欢写 SQL 码农的福音,相对于 SqlHelper 它更加方便,据统计 10个 .NETer 有 9个 用过 Dapper。

    由于 .NET 环境的特殊,对 Lambda 表达式树的喜爱,于是市面上有很多出现了基于 Dapper 的轻量级 ORM,它们几乎都有共同特点,让 Dapper 支持 Lambda 表达式树,写起来顺畅如流水。

    今天介绍一款本身功能已经很强大的 ORM,他提供一个隐藏得比较深的 API 功能,使用起来和 Dapper 没什么两样。

    了解 Lambda 表达式树

    这要先从 Lambda 表达式开始说起,词语中少了一个“树”字,差别甚大。

    表达式,如下各种语法糖骚操作,产生的 IL 一模一样:

    //使用C# 2.0中的匿名方法获取字符串长度
    Func<string, int> strLength = delegate(string str) { return str.Length; };
    Console.WriteLine(strLength("Hello World!"));
    
    //使用Lambda表达式
    //(显式类型参数列表)=> {语句},lambda表达式最冗长版本
    strLength = (string str) => { return str.Length; };
    Console.WriteLine(strLength("Hello World!"));
    
    //单一表达式作为主体
    //(显式类型参数列表)=> 表达式
    strLength = (string str) => str.Length;
    Console.WriteLine(strLength("Hello World!"));
    
    //隐式类型的参数列表
    //(隐式类型参数列表)=> 表达式
    strLength = (str) => str.Length;
    Console.WriteLine(strLength("Hello World!"));
    
    //单一参数的快捷语法
    //参数名 => 表达式
    strLength = str => str.Length;
    Console.WriteLine(strLength("Hello World!"));
    

    而表达式树呢,代码写起来跟表达式差不多,如下:

    Expression<Func<string, int>> strLength = str => str.Length;
    

    表达式树不支持代码块(花括号)

    力求书写简单,一般情况我们都是这样写的,虽然它和表达式代码写起来几乎一样,但是返回值和表达式不一样,多了一个泛型 Expression<>。

    表达式树也称表达式目录树,将代码以一种抽象的方式表示成一个对象树,树中每个节点本身都是一个表达式。表达式树不是可执行代码,它是一种数据结构。它是代码在编译期间将编写的代码转换成一个树结构,以便后续进行逆向解析。

    如上:(strLength.Body as MemberExpression).Member.Name 可以得到值 "Length"

    由于表达式树可逆向解析的特点,近十年来 EF 是一直是带头大哥,国产每年都要整出好几个 ORM,大部分都是基于表达式树解析做的。

    表达式树解析

    .NET 技术文章从来不缺少表达式树解析的这类文章,有兴趣的可以百度搜索一下,很多很多,但是想做完美可不是件简单事。

    FreeSql 在表达式树解析上做了下足了工夫,举例:

    1、子表 in 查询

    .Where(a => fsql.Select<T>().ToList(b => b.Id).Contains(a.Id))
    //WHERE a.Id in (select id from t)
    

    2、子表 exists 查询

    .Where(a => fsql.Select<T>().Any(b => b.Id == a.Id))
    //WHERE exists(select 1 from t where Id = a.Id)
    

    3、日期格式化

    ToList(a => a.CreateTime.ToString("HH:mm:ss"))
    //date_format(a.`CreateTime`, "%H:%i:%s")
    

    4、开窗函数

    ToList(a => SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue())
    //rank() over(order by a.Id, b.EdiId desc)
    

    5、Join 子表

    ToList(a => string.Join(",", fsql.Select<StringJoin01>().ToList(b => b.Id)))
    //(SELECT group_concat(b.`Id` separator ",") FROM `StringJoin01` b) 
    

    这些特性在不同的数据库,都需要做相应适配实现,FreeSql 还支持对导航属性的表达式树解析,说这些只想证明做到细致真的不容易。

    与其自己造着麻烦,不如直接拿来主义使用?

    Ado.Net 扩展实现

    与其自己造着麻烦,不如直接拿来主义使用?FreeSql 提供了一种非主打的 API 使用习惯,使用起来跟 Dapper 没什么区别。

    支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/MsAccess 十多种数据库适配,支持 Ado.net/Odbc,并且支持 .NetFramework 4.0 平台、.NET5.0、.NET Core2.1 + 平台。

    第一步:以数据库 SqlServer 访问为例,只需要安装已经划分好的小包:

    dotnet add packages FreeSql.Provider.SqlServer
    

    or

    Install-Package FreeSql.Provider.SqlServer
    

    第二步:建立实体类

    class TestConnectionExt {
        public Guid id { get; set; }
        public string title { get; set; }
        public DateTime createTime { get; set; } = DateTime.Now;
    }
    

    第三步:开始 CRUD

    using (var conn = new SqlConnection(connectString)) {
        var list = conn.Select<TestConnectionExt>().Where(a => a.id == item.id).ToList();
    }
    
    using (var conn = new SqlConnection(connectString)) {
        var item = new TestConnectionExt { title = "testinsert" };
        var affrows = conn.Insert(item).ExecuteAffrows();
    }
    
    using (var conn = new SqlConnection(connectString)) {
        var affrows = conn.Update<TestConnectionExt>()
            .Where(a => a.Id == xxx)
            .Set(a => a.title, "testupdated")
            .ExecuteAffrows();
    }
    
    using (var conn = new SqlConnection(connectString)) {
        var affrows = conn.Delete<TestConnectionExt>()
            .Where(a => a.Id == xxx)
            .ExecuteAffrows();
    }
    

    添加或更新:

    using (var conn = new SqlConnection(connectString)) {
        var affrows = conn.InsertOrUpdate<TestConnectionExt>()
            .SetSource(item)
            .ExecuteAffrows();
    }
    

    如上添加、删除、修改、查询,已经支持实体类操作,并且支持批量插入、批量更新、批量删除、多表查询、导航属性查询。

    可以享用 FreeSql 几乎所有功能。

    思考:使用这种 API 貌似可以很轻松的接入到 abp vnext 中?

    结束语

    FreeSql 使用世界上最宽松的开源协议 MIT 托管于 github:https://github.com/dotnetcore/FreeSql 目前已发布经历两年高频率迭代的稳定版本 v2.0,欢迎关注和使用。

    支持 .NetFramework 4.0+、.NetCore 2.1+、Xamarin 等支持 NetStandard 所有运行平台。

    支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/MsAccess 数据库,支持 Ado.net/Odbc。

    QQ群:4336577(已满)、8578575(在线)、52508226(在线)


    以上信息来源于网络,如有侵权,请联系站长删除。

    TAG:使用者 礼物 Dapper

  • 上一篇:木星和土星将在彼此的0.1度范围内,在800年内形成第一个可见的“双行星”
  • 与“献给 Dapper 使用者的一份礼物”相关的资讯
  • 保留(您的数据远离的圣诞礼物 - 以及如何防止这一点
  • 如何将 Dapper 换成 SqlSugar orM
  • 在黑色星期五购买最好的东西:礼品卡?小工具?优惠和最糟糕的产品
  • AA.Dapper升级了
  • 【七夕特殊礼物】Dubbo学习之SPI实战与debug源码