FreeSql是一个支持.NET Core 2.1+、.NET Framework 4.0+ 以及 Xamarin的ORM(Object Relational Mapping)对象关系映射的组件

支持丰富的表达式函数及类型映射,但还是有不少开发者需要执行自定义SQL。

我一般会推荐他们使用
List<T> list = fsql.Ado.Query<T>("select * from t1");
等类似的操作,IAdo下有大量的ADO.NET基础的调用操作。但开发者还想使用类似Page,Skip,OrderBy等方法。鉴于fsql可以生成SQL,可以将不同的SQL组合,实现更加复杂的功能。

  • 引用包

dotnet add packages FreeSql
dotnet add packages FreeSql.Provider.Sqlite
  • .NET Core 单例 Startup.cs

public void ConfigureServices(IServiceCollection services)
{IFreeSql fsql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=db1.db").UseAutoSyncStructure(true) //自动同步实体结构到数据库,FreeSql不会扫描程序集,只有CRUD时才会生成表。.Build();services.AddSingleton<IFreeSql>(fsql);
}

可使用以下方式实现

WithSql 自定义SQL

定义实体类

public class TestClass{[Column(Name = "ID", IsPrimary = true)]public string No { get; set; }public int? Age { get; set; }public string Name { get; set; }[Column(Name = "BIRTH_DAY")]public DateTime? Birthday { get; set; }public decimal Point { get; set; }public Sex? Sex { get; set; }}public class TestClssDto{public string ID { get; set; }public int? Age { get; set; }}

不同的查询方式。

  • 返回DataTable

  • 返回List<Tuplue> 即List<(string,string)>元组

  • 返回List<object> 且能支持分页

  • 返回List<TestClassDto>且能支持分页

1.返回DataTable

DataTable dt1 = _fsql.Select<object>().WithSql("select * from TestClass ").ToDataTable("ID,Age");
SELECT ID,Age FROM(select * from TestClass  ) a

2.返回DataTable

DataTable dt2 = _fsql.Select<object>().WithSql("select * from TestClass ").ToDataTable("*");
SELECT *
FROM ( select * from TestClass  ) a

3.返回List<Tuplue> 即List<(string,string)> 元组

List<(string,string)> list1 = _fsql.Select<object>().WithSql("select * from TestClass ").ToList<(string, string)>("ID,Age");
SELECT ID, AgeFROM(select * from TestClass  ) a

4.返回List<object>

var list2 = _fsql.Select<object>().WithSql("select * from TestClass ").ToList<object>("*");
SELECT *FROM(select * from TestClass  ) a

5.返回List<object> 且能支持分页

var list3 = _fsql.Select<object>().WithSql("select * from TestClass ").WhereIf(true, "1=1").Page(1, 10).OrderBy("ID DESC").ToList<object>("ID,Age");
SELECT ID, AgeFROM(select * from TestClass  ) aWHERE(1 = 1)ORDER BY ID DESClimit 0,10

6.返回List<TestClassDto>且能支持分页

var list4 = _fsql.Select<object>().WithSql("select * from TestClass ").WhereIf(true, "1=1").Page(1, 10).OrderBy("ID DESC").ToList<TestClssDto>("ID,Age");
SELECT ID, AgeFROM(select * from TestClass  ) aWHERE(1 = 1)ORDER BY ID DESClimit 0,10

通过 WithSql+ ToSQL实现 Union ALL 查询方法

1、二次 ISelect 查询:WithSql 使用多次,等于 UNION ALL 查询

WithSql 使用多次为 UNION ALL 查询,所以我们可以利用 ISelect.ToSql(FieldAliasOptions.AsProperty) 得到生成的 SQL,如下:

var sql1 = fsql.Select<Topic>().Where(a => a.Title.Contains("xxx")).ToSql();
var sql2 = fsql.Select<Topic>().Where(a => a.Title.Contains("yyy")).ToSql();fsql.Select<Topic>().WithSql(sql1).WithSql(sql2).ToList();
SELECT  * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM ( SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Title`) LIKE '%xxx%') ) a) ftbUNION ALLSELECT  * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM ( SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Title`) LIKE '%yyy%') ) a) ftb

2、跨分表查询:AsTable 相同实体多次操作,等于 Union ALL 查询

var sql = fsql.Select<User>().AsTable((type, oldname) => "table_1")a.AsTable((type, oldname) => "table_2").ToSql(a => a.Id);
select * from (SELECT a."Id" as1 FROM "table_1" a) ftb
UNION ALL
select * from (SELECT a."Id" as1 FROM "table_2" a) ftb

3、利用 ToSql 拼接新的 SQL,使用 IAdo 执行

var sql1 = fsql.Select<Topic>().Where(a => a.Id > 100 && a.Id < 200).ToSql(a => new { a.Id, a.Title }, FieldAliasOptions.AsProperty);
var sql2 = fsql.Select<Topic>().Where(a => a.Id > 1001 && a.Id < 1200).ToSql(a => new { a.Id, a.Title }, FieldAliasOptions.AsProperty);fsql.Ado.CommandFluent($"{sql1} UNION ALL {sql2}").ExecuteDataTable();

分页问题

Union All 之后 如果直接 分页会有一个问题。请看具体示例

多次WithSql+Page存在问题:每个WithSql内都有一个Page分页

var sql1 = fsql.Select<Topic>().Where(a => a.Title.Contains("xxx")).ToSql();
var sql2 = fsql.Select<Topic>().Where(a => a.Title.Contains("yyy")).ToSql();fsql.Select<Topic>().WithSql(sql1).WithSql(sql2).Page(1, 20).ToList();
SELECT  * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM ( SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Title`) LIKE '%xxx%') ) a
limit 0,20) ftbUNION ALLSELECT  * from (SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM ( SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime` FROM `tb_topic` a WHERE ((a.`Title`) LIKE '%yyy%') ) a
limit 0,20) ftb

多个sql union all使用withsql,直接Page分页,会导致每个子表都生效,子表都生成分页。

WithSql 可以和 AsTable 实现分表的功能。

分表跨表查询的时候,分页是要向每个子表(即每个WithSql中的SQL分页)都生效。

解决方案

多次withsql,如需分页,需要按下面的二步操作

  • 第一步:通过witsql,将二个sql组成一个sql。

var sql = fsql.Select<Topic>().WithSql("SELECT * FROM tb_topic where id > 11").WithSql("SELECT * FROM tb_topic where id < 10").ToSql("*")

如上生成的UOION ALL的sql

SELECT  * from (SELECT * FROM ( SELECT * FROM tb_topic where id > 11 ) a) ftbUNION ALLSELECT  * from (SELECT * FROM ( SELECT * FROM tb_topic where id < 10 ) a) ftb
  • 第二步:之后 调用Page则是通过Union ALL后的结果上分页

var sql2 = g.mysql.Select<Topic>().WithSql(sql).Page(2, 10).ToSql();
SELECT a.`Id`, a.`Clicks`, a.`TypeGuid`, a.`Title`, a.`CreateTime`
FROM ( SELECT  * from (SELECT *FROM ( SELECT * FROM tb_topic where id > 11 ) a) ftbUNION ALLSELECT  * from (SELECT *FROM ( SELECT * FROM tb_topic where id < 10 ) a) ftb ) a
limit 10,10

更多

  • 参考官网http://freesql.net/guide/getting-started.html

  • GitHubhttps://github.com/dotnetcore/FreeSql/

FreeSql使用WithSql+ ToSQL 查询数据相关推荐

  1. FreeSql (十五)查询数据

    FreeSql在查询数据下足了功能,链式查询语法.多表查询.表达式函数支持得非常到位. IFreeSql fsql = new FreeSql.FreeSqlBuilder().UseConnecti ...

  2. FreeSql (十)更新数据

    FreeSql支持丰富的更新数据方法,支持单条或批量更新,在特定的数据库执行还可以返回更新后的记录值. var connstr = "Data Source=127.0.0.1;Port=3 ...

  3. FreeSql (九)删除数据

    删除是一个非常危险的操作,FreeSql对删除支持并不强大,仅支持了单表有条件的删除方法. 不想过多的介绍拉长删除数据的系列文章,删除数据的介绍仅此一篇. 若Where条件为空的时候执行方法,Free ...

  4. FreeSql (八)插入数据时指定列

    插入数据时指定列,和忽略列对应,未被指定的列将被忽略. var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Passwor ...

  5. java查询mysql装载bean_jsp与javabean链接mysql数据库并查询数据表的简单实例源码

    jsp与javabean链接mysql数据库并查询数据表的简单实例源码.这个简单的实例是给新手学习的,或者一些高手临时忘记怎么使用jsp操作mysql数据库时候查找的,包括了建立mysql数据库连接的 ...

  6. JUnit测试类完成后事务是默认 回滚的。只能查询数据,不能增删改。

    JUnit测试类完成后事务是默认 回滚的.只能查询数据,不能增删改. 在测试类或者测试方法上面加上注解 @Rollback(false)  表示事物不回滚,这样数据就可以提交到数据库中了. 转载于:h ...

  7. Elasticsearch 查询数据的工作原理是什么?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:8rr.co/GsAa 面试题 ES 写入数据的工作原理是什 ...

  8. Statement接口实现查询数据、添加数据

    本文介绍了Statement接口实现查询数据.添加数据.在JDBC的基本应用中,介绍了使用Statement接口查询和添加数据的步骤.重点在于使用getConnection()方法来连接数据库,创建S ...

  9. mysql三表查询数据重复_解决mybatis三表连接查询数据重复的问题

    此问题的产生,主要是数据库的字段名一样导致 三张表 DOCTOR JOB OBJECT 有问题的查询语句和查询结果是: SELECT d.*,j.*,o.* from (select d.*,rown ...

最新文章

  1. onchange事件与onpropertychange事件的区别
  2. 闽高校计算机二级c语言模拟器,闽高校计算机二级C语言模拟卷及答案.doc
  3. 【Leetcode | 顺序刷题】杂项目录
  4. java线程池执行器_Java线程池ThreadPoolExecutor的使用
  5. 某一天,忽然发现自己坚持不下去了。(无关计算机,只是一些自己的困惑和感想)
  6. linux内核系列之二_资源
  7. Java的括号使用规则_java编码规范
  8. 如何卸载赛门铁克symantec,ivanti
  9. 在method方法被调用之后,仅打印出a=100,b=200,请写出method方法的代码
  10. 拿姐姐身份证登记结婚竟然成了!婚姻户籍信息共享难在哪儿
  11. 共轭函数和原函数的关系
  12. 计算机中英文字录入教案,文字录入教案.doc
  13. 什么是等级保护?为什么要开展等级保护?
  14. Python运维开发从入门到精通学习 Day4
  15. 2021年河南高考--各高校在河南录取分数线预测(本科二批——理科)
  16. 5G NR 下行同步SSB(4)-- 频域配置多个SSB
  17. cnn 分层 可视化 网站_如何可视化分层数据以显示整体关系
  18. [计算机基础]整理计算机的数据计量单位
  19. 国家/行业标准查询及下载全流程
  20. 切西瓜小游戏评测玩法规则

热门文章

  1. php验证码函数 使用imagestring() imagefttext()设置字体大小
  2. 缩放手势 ScaleGestureDetector 源码解析,这一篇就够了
  3. 看出每个应用程序最高可用内存是多少
  4. arcgis server 无法手动删除切片
  5. hdu 4493 Tutor (水 精度)
  6. 微软将终止免费的条码标签服务
  7. kompozer如何启动_使用KompoZer创建网站
  8. 白色裤子为什么会沾上蓝色_什么是蓝色的,为什么它可以在Mac上运行?
  9. 共享没有权限访问权限_如何与家人共享SmartThings访问权限
  10. 查看模拟器使用端口_为什么我们仍然使用模拟音频端口?