ShadowSql是面向接口模块化可插拔可扩展的工具

  • ShadowSql不是全家桶
  • 不把所有功能都做一个项目里面就是为了大家不一次引用所有的nuget包
  • 大家可以先判断需要哪些功能,再引用对应的nuget包
  • 当然同时引用这6个nuget包也是可以的

一、相关项目简介

名称 项目 Nuget包 依赖 大小 主要用途
精简版 ShadowSql.Core ShadowSql.Core 147K 简洁高效拼接sql
易用版 ShadowSql ShadowSql ShadowSql.Core 96K(+147K) 泛型表操作、链式拼接sql
表达式版 ShadowSql.Expressions ShadowSql.Expressions ShadowSql.Core 75K(+147K) 表达式树操作、链式拼接sql
DDL Shadow.DDL Shadow.DDL ShadowSql.Core 15K(+147K) 拼接CreateTable、表Schema支持
Dapper Dapper Dapper 240K 执行sql、类型Mapping
精简版扩展 Dapper.Shadow.Core ShadowSql.Dapper.Core ShadowSql.Core和Dapper 17K(+387K) 执行ShadowSql.Core拼接的sql
易用版扩展 Dapper.Shadow ShadowSql.Dapper ShadowSql.Dapper.Core、ShadowSql.Core、ShadowSql和Dapper 35K(+500K) 执行ShadowSql拼接的sql

二、如果选型

  • 主要看个人或团队偏好

1. 偏好Lambda选表达式版

  • 表达式树是Lambda的影子,可以生成委托,但这里只解析表达式树
  • 表达式版提供类EF的查询体验
  • 表达式树会用到反射,性能上会有点损耗,对比带来的便利性完全是可以接受的
  • 如果使用参数查询并缓存sql复用,完全可以忽略这个性能损耗,甚至可以忽略整个拼写sql的性能消耗
  • 表达式版搭配Dapper.Shadow.Core或者直接搭配Dapper甚至ADO.NET使用

1.1 EFCore示例

  • ShadowSql不含EFCore的功能,这个示例是为了和表达式版对比
var query = context.Set<User>("Users")
.Where(u => u.Status)
.Take(10)
.Skip(20)
.OrderByDescending(u => u.Id)
.Select(u => new { u.Id, u.Name });

1.2 表达式版示例

  • 表达式版可以写出与EFCore类似的代码
var select = db.From("Users")
.ToSqlQuery<User>()
.Where(u => u.Status)
.Take(10)
.Skip(20)
.Desc(u => u.Id)
.ToSelect()
.Select(u => new { u.Id, u.Name });

1.3 表达式版参数化查询示例

  • 表达式版可以写出与EFCore类似的代码
var select = _db.From("Users")
.ToSqlQuery<User>()
.Where<UserParameter>((u, p) => u.Id == p.Id2 && u.Status)
.Take(10)
.Skip(20)
.Desc(u => u.Id)
.ToSelect()
.Select(u => new { u.Id, u.Name });
// MsSql生成sql: SELECT [Id],[Name] FROM [Users] WHERE [Id]=@Id2 AND [Status]=1 ORDER BY [Id] DESC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY

1.4 表达式版更多功能

2. 偏好链式查询选易用版

  • 易用版支持泛型表操作几乎无性能损耗(对比精简版)
  • 每个模型类最好定义数据表影子类(联表定义别名表),以便做到sql编译检测
  • 不定义数据表影子类可以用按字段查询严格查询
  • ShadowSql搭配Dapper.Shadow或Dapper.Shadow.Core或直接搭配Dapper甚至ADO.NET使用

2.1 易用版示例

var select = new UserTable()
.ToSqlQuery()
.Where(table => table.Status.EqualValue(true))
.Take(10, 20)
.Asc(table => table.Id)
.ToSelect()
.Select(table => [table.Id, table.Name]);
// MsSql生成sql: SELECT [Id],[Name] FROM [Users] WHERE [Id]=@Id2 AND [Status]=1 ORDER BY [Id] DESC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY

2.2 易用版更多功能

3. 有“洁癖”选精简版

  • 使用精简版也可以定义数据表影子类(联表定义别名表)
  • 查询时使用列或者数据表的列,这样代码可读性高,也可以做到sql编译检测
  • ShadowSql.Core搭配Dapper.Shadow.Core或者直接搭配Dapper甚至ADO.NET使用

3.1 精简版示例

var table = new UserTable();
var query = new TableSqlQuery(table)
.Where(table.Status.EqualValue(true));
var cursor = new TableCursor(query)
.Take(10)
.Skip(20)
.Asc(table.Id);
var select = new CursorSelect(cursor)
.Select(table.Id, table.Name);

3.2 易用版更多功能

4. 需要CreateTable或表Schema的选DDL

  • DDL可以搭配易用版或表达式版
  • 参看DDL简介

4.1 CreateTable

    ColumnSchema id = new("Id", "INTEGER") { ColumnType = ColumnType.Identity | ColumnType.Key };
ColumnSchema name = new("Name", "TEXT");
TableSchema table = new("Students", [id, name]);
CreateTable create = new(table);
// Sqlite生成sql: CREATE TABLE "Students"("Id" INTEGER PRIMARY KEY AUTOINCREMENT,"Name" TEXT)

4.2 表Schema查询示例

UserTable table = new("Users", "tenant1");
var query = new TableQuery(table)
.And(table.Status.EqualValue(true));
var cursor = new TableCursor(query, 10, 20)
.Desc(table.Id);
var select = new CursorSelect(cursor)
.Select(table.Id, table.Name);
// MsSql生成sql: SELECT [Id],[Name] FROM [tenant1].[Users] WHERE [Status]=1 ORDER BY [Id] DESC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
public class UserTable(string tableName = "Users", string schema = "")
: TableSchema(tableName, [Defines.Id, Defines.Name, Defines.Status], schema)
{
#region Columns
public readonly ColumnSchema Id = Defines.Id;
new public readonly ColumnSchema Name = Defines.Name;
public readonly ColumnSchema Status = Defines.Status;
#endregion class Defines
{
public static readonly ColumnSchema Id = new("Id") { ColumnType = ColumnType.Key };
public static readonly ColumnSchema Name = new("Name");
public static readonly ColumnSchema Status = new("Status");
}
}

4.3 DDL+表达式版查询示例

var select = new TableSchema("Users", [], "tenant1")
.ToSqlQuery<User>()
.Where(u => u.Status)
.Take(10, 20)
.Desc(u => u.Id)
.ToSelect();
// MsSql生成sql: SELECT * FROM [tenant1].[Users] WHERE [Status]=1 ORDER BY [Id] DESC OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY

5. 易用版和表达式版一般不一起使用

  • 易用版和表达式版有同名类和方法,在不同命名空间
  • 同一个类引用命名空间ShadowSql和ShadowSql.Expressions调用某些方法会报不明确引用错误
  • 同一项目一个类用易用版,另一个类用表达式版是可行的

我们可以把ShadowSql当做乐高玩具一下,通过自己的组装可以实现意想不到的美妙效果

源码托管地址: https://github.com/donetsoftwork/Shadow,也欢迎大家直接查看源码。

gitee同步更新:https://gitee.com/donetsoftwork/Shadow

文档地址: https://donetsoftwork.github.io/Shadow/expression/index.html

如果大家喜欢请动动您发财的小手手帮忙点一下Star。

ShadowSql.net之正确使用方式的更多相关文章

  1. iOS开发小技巧--相机相册的正确打开方式

    iOS相机相册的正确打开方式- UIImagePickerController 通过指定sourceType来实现打开相册还是相机 UIImagePickerControllerSourceTypeP ...

  2. const、static和extern的正确使用方式

    我们在看一些大牛的第三方时,里面会出现很多const.static和extern,尤其是const和static,const和extern的结合使用,直接令很多小伙伴懵逼了,今天就详细讲解一下这三个关 ...

  3. @synthesize的正确使用方式

    @synthesize的正确使用方式 一. @synthesize的错误使用方式 类1和类2是继承关系, name是类1的属性 但是类2的实现里加入了@synthesize name = _name; ...

  4. Xcode 的正确打开方式——Debugging(转载)

    Xcode 的正确打开方式——Debugging   程序员日常开发中有大量时间都会花费在 debug 上,从事 iOS 开发不可避免地需要使用 Xcode.这篇博客就主要介绍了 Xcode 中几种能 ...

  5. 以正确的方式开源 Python 项目

    以正确的方式开源 Python 项目 大多数Python开发者至少都写过一个像工具.脚本.库或框架等对其他人也有用的工具.我写这篇文章的目的是让现有Python代码的开源过程尽可能清 晰和无痛.我不是 ...

  6. 以正确的方式开源 Python 项目 - 技术翻译 - 开源中国社区

    以正确的方式开源 Python 项目 - 技术翻译 - 开源中国社区 以正确的方式开源 Python 项目 英文原文:Open Sourcing a Python Project the Right ...

  7. 以正确的方式开源 Python 项目(转)

    大多数Python开发者至少都写过一个像工具.脚本.库或框架等对其他人也有用的工具.我写这篇文章的目的是让现有Python代码的开源过程尽可能清晰和无痛.我不是简单的指——“创建一个GitHub库,提 ...

  8. IntelliJ IDEA中Mapper接口通过@Autowired注入报错的正确解决方式

    转载请注明来源:四个空格 » IntelliJ IDEA中Mapper接口通过@Autowired注入报错的正确解决方式: 环境 ideaIU-2018.3.4.win: 错误提示: Could no ...

  9. C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别

    C#语法——泛型的多种应用   本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...

  10. Redis实现分布式锁的正确使用方式(java版本)

    Redis实现分布式锁的正确使用方式(java版本) 本文使用第三方开源组件Jedis实现Redis客户端,且只考虑Redis服务端单机部署的场景. 分布式锁一般有三种实现方式: 1. 数据库乐观锁: ...

随机推荐

  1. qa 工作

    1.定流程--监控参照规范(cmmi,公司自己的,scrum[例会.启动会])--产出物报告 (项目维度)-配置--经盈.财务 2.培训组织-组织讲师(知识库).外部拓展

  2. Selenium KPI接口 键盘操作

    实现功能:百度搜索框输入selenium->复制内容->sogo搜索框粘贴内容. 首先导入Keys方法 使用格式: driver.findelementbyid("kw" ...

  3. CentOS7图形化界面和命令行界面之间的转换

    最近在学习Lunix操作系统下的CentOS7系统,参考了网页上大多数的资料并进行在自己的亲身实践,最终想要记录一下我在CentOS7系统中有关命令行和图形化界面之间的转换.1.查看当前的默认界面形式 ...

  4. 关于SIFT,GIFT在旋转不变性上的对比实验

    目录 关于SIFT,GIFT在旋转不变性上的对比实验 回顾 准确率测试 总结 核心代码 关于SIFT,GIFT在旋转不变性上的对比实验 这篇文章不讨论SIFT,GIFT的实现原理,只从最终匹配结果的准 ...

  5. Docker Commonds

    脑子不够用,记录下自己所学所用的命令,备忘...不断补充. 最最基本的命令 查看 docker 信息 docker info 查看 docker 版本及相关信息 docker version 仅查看 ...

  6. 4G模块详解

    在之前的教程中,无线通信技术我们学习了蓝牙和 WiFi,今天我们要来学习 4G. 4G 模块在距离上有个突破,它不像蓝牙短距离,也不像 WiFi 只能在局域网,4G 模块可使用户无论在哪,只要有 4G ...

  7. Linux终端居然也可以做文件浏览器?

    大家好,我是良许. 在抖音上做直播已经整整 5 个月了,我很自豪我一路坚持到了现在[笑脸] 最近我在做直播的时候,也开始学习鱼皮大佬,直播写代码.当然我不懂 Java 后端,因此就写写自己擅长的 Sh ...

  8. P3392 涂国旗 题解

    题目大意 题目真的是不说人话...... 有一个国家的国旗是由一个 N * M 的方格组成的.如果想要这面国旗合法,就必须满足要求: 国旗从上到下必须是白色.蓝色和红色,顺序不能改变. 每一种颜色都至 ...

  9. CH182的ESP32驱动

    CH182的ESP32驱动需要自取 https://files.cnblogs.com/files/blogs/745523/esp-eth.zip?t=1739322979&download ...

  10. HTB-UnderPass

    该靶机nmap扫描udp发现161端口snmp服务,利用snmpwalk扫描得到目录信息,使用dirsearch扫描得到一个yml文件,存放数据库账号密码,记录下来,此时需要登录口,使用字典扫描拼接/ ...