喜闻乐见最新的ORM查询BUG,看看有没你关注的
起因,想测试下查询语句的生成,按以下逻辑代码示例
var query = rep.GetLambdaQuery().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).Join<TestEntityItem>((a, b) => a.a1 == b.TestEntityId);//第一次关联
var join2 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
.Join<TestEntity>((a, b) => a.a3 == b.Id);//第二次关联
join2.Select((a, b) => new
{
a.a4,
b.Id
});
这里为多层嵌套关联,是一个比较常见到场景,根据逻辑意义和语法支持,多数ORM都能实现这个查询
对应sql为
select
t4.[a4],
t1.[Id]
from
(
select
t2.[a1] as a3,
t3.[Name] as a4
from
(
select
t1.[Id] as a1,
t1.[F_String] as a2
from
[TestEntity] t1
LIMIT 0, 100
) t2
Inner join [TestEntityItem] t3 on t2.a1 = t3.[TestEntityId]
) t4
Inner join [TestEntity] t1 on t4.a3 = t1.[Id]
测试了最近看到的几个ORM
Chloe
var query = getContext().Query<TestEntity>().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).Join<TestEntityItem>(JoinType.InnerJoin, (a, b) => a.a1 == b.TestEntityId);
var query3 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
.Join<TestEntity>(JoinType.InnerJoin, (a, b) => a.a3 == b.Id).Select((a, b) => new
{
a.a4,
b.Id
});
var sql = query3.ToString();
Console.WriteLine($"{GetType().Name}: {sql}");
输出为
SELECT
[TestEntityItem].[Name] AS [a4],
[TestEntity0].[Id]
FROM
(
SELECT
[TestEntity].[Id] AS [a1],
[TestEntity].[F_String] AS [a2]
FROM
[TestEntity] AS [TestEntity]
LIMIT
100 OFFSET 0
) AS [T]
INNER JOIN [TestEntityItem] AS [TestEntityItem] ON [T].[a1] = [TestEntityItem].[TestEntityId]
INNER JOIN [TestEntity] AS [TestEntity0] ON [T].[a1] = [TestEntity0].[Id]
在第一次关联生成的还正常,第二次关联就不对了
FastFramework
var query = getDb().Query<TestEntity>().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).InnerJoin<TestEntityItem>((a, b) => a.a1 == b.TestEntityId);
var query2 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
.InnerJoin<TestEntity>((a, b) => a.a3 == b.Id).Select((a, b) => new
{
a.a4,
b.Id
});
var sql = query2.ToSqlString();
Console.WriteLine($"{GetType().Name}: {sql}");
输出
SELECT [p1].[a4] AS [a4],[p2].[Id] AS [Id] FROM [TestEntity] [p1]
INNER JOIN [TestEntityItem] [p2] ON ( [p1].[a1] = [p2].[TestEntityId] )
INNER JOIN [TestEntity] [p2] ON ( [p1].[a3] = [p2].[Id] ) LIMIT 0,100
完全不对
FreeSql
db.Aop.CurdAfter += (s, e) =>
{
Console.WriteLine($"{GetType().Name}: {e.Sql}");
};
var query = db.Select<TestEntity>().Take(100);
var query2 = query.WithTempQuery(b => new { a1 = b.Id, a2 = b.F_String });
var query3 = query2.FromQuery(db.Select<TestEntityItem>()).InnerJoin((a, b) => a.a1 == b.TestEntityId);
var query4 = query3.WithTempQuery((a, b) => new { a3 = a.a1, a4 = b.Name }).FromQuery(db.Select<TestEntity>()).InnerJoin((a, b) => a.a3 == b.Id); ;
var result = query4.WithTempQuery((a, b) => new
{
a.a4,
b.Id
}).ToList();
输出
SELECT *
FROM (
SELECT a."a4", b."Id"
FROM (
SELECT a."a1" "a3", b."Name" "a4"
FROM (
SELECT a."Id" "a1", a."F_String" "a2"
FROM "TestEntity" a
limit 0,100 ) a
INNER JOIN "TestEntityItem" b ON a."a1" = b."TestEntityId" ) a
INNER JOIN "TestEntity" b ON a."a3" = b."Id" ) a
基本正确,少了as语法,看着有些怪异
SqlSugar
var query = db.Queryable<TestEntity>().Take(100);
var query2 = query.Select(b => new { a1 = b.Id, a2 = b.F_String });
var query3 = query2.InnerJoin<TestEntityItem>((a, c) => a.a1 == c.TestEntityId);
var query4 = query3.Select((a, c) => new { a3 = a.a1, a4 = c.Name })
// .InnerJoin<TestEntity>((d, e) => d.a3 == e.Id).Select((d, e) => new
//{
// d.a4,
// e.Id
//})
;
var sql = query4.ToSqlString();
Console.WriteLine($"{GetType().Name}: {sql}");
注意第二次关联注释掉了,如果加上直接异常
System.Exception:“中文提示 : Join TestEntity 错误, 请把 (d,e)=> 改成 (a,c,TestEntity )=>
English Message : Join TestEntity error , Please change (d,e)=> to (a,c,TestEntity )=>.”
第一次关联输出
SELECT
`a`.`a1` AS `a3`,
`b`.`Name` AS `a4`
FROM
(
SELECT
*
FROM
(
SELECT
`Id` AS `a1`,
`F_String` AS `a2`
FROM
`TestEntity`
LIMIT
0, 100
) MergeTable
) `a`
Inner JOIN `TestEntityItem` `b` ON (`a`.`a1` = `b`.`TestEntityId`)

革命尚未成功,同志仍须努力
喜闻乐见最新的ORM查询BUG,看看有没你关注的的更多相关文章
- 灵活使用 SQLAlchemy 中的 ORM 查询
之前做查询一直觉得直接拼 SQL 比较方便,用了 SQLAlchemy 的 ORM 查询之后,发现也还可以,还提高了可读性. 这篇文章主要说说 SQLAlchemy 常用的 ORM 查询方式,偏实践. ...
- Django 源码小剖: Django ORM 查询管理器
ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...
- Django ORM 查询管理器
Django ORM 查询管理器 ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言 ...
- Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复
写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...
- ORM查询条件
模板: from django.db import models class Article(models.Model): title = models.CharField(max_length=20 ...
- Django之ORM查询复习与cookie
ORM查询总结: models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwa ...
- ORM( ORM查询13种方法3. 单表的双下划线的使用 4. 外键的方法 5. 多对多的方法 ,聚合,分组,F查询,Q查询,事务 )
必知必会13条 <1> all(): 查询所有结果 <2> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或 ...
- Python学习---ORM查询之基于对象的正向/反向/聚合/分组/Q/F查询
ORM查询之基于对象的正向查询与反向查询 对象形式的查询 # 正向查询 ret1=models.Book.objects.first() print(ret1.title) print(ret1.pr ...
- ORM查询练习
ORM查询练习 Django ORM ORM查询的练习题 ORM代码 from django.db import models # Create your models here. class Pu ...
- Django框架 之 ORM查询操作详解
Django框架 之 ORM查询操作详解 浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Py ...
随机推荐
- TypeScript:接口
介绍 TypeScript的核心原则之一是对值所有的结构类型进行类型检查.在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义约束. 接口的基本使用 interface ...
- 使用kafka自带脚本进行压力测试
前言 kafka官方自带压力测试脚本: 消费者压力测试:kafka-consumer-perf-test.sh 生产者压力测试:kafka-producer-perf-test.sh 测试节点: 17 ...
- Ubuntu20.04 下编译和运行 FreeSWITCH的问题汇总
1. Ubuntu20.04 下编译和运行 FreeSWITCH的问题汇总 1.1. 环境 Ubuntu20.04.2 LTS (Linux 5.4.0-152-generic x86_64 GNU/ ...
- Go 如何正确关闭通道
序言 Go 在通道这一块,没有内置函数判断通道是否已经关闭,也没有可以直接获取当前通道数量的方法.所以对于通道,Go 显示的不是那么优雅.另外,如果对通道进行了错误的使用,将会直接引发系统 panic ...
- 使用pycharm脚本发送钉钉群通知
使用Pychon脚本发送钉钉群通知 我们可以使用钉钉的机器人助手发送群通知,只需要非常简单的配置就可以实现,而没有任何的成本. 1) 首先我们要在钉钉群里添加一个机器人助手 选择智能群助手,然后选择添 ...
- 使用antd-mobile遇到的坑
在使用antd-mobile中的组件的时候,遇到了一些比较棘手的问题,经过查找相关资料和网上的帮助,在此整理出了问题以及解决办法: 在引入antd-mobile的时候,根据官网提供的文档: 1,首先安 ...
- FFmpeg中的常用结构体分析
一.前言 在学习使用FFmpeg进行编解码时,我们有必要先去熟悉FFmpeg中的常用结构体,只有对它们的含义和用途有深刻的了解,我们才能为后面的学习打下坚实的基础.所以,这篇文章将会介绍这些常用的结构 ...
- 数据库重构之路,以 OrientDB 到 NebulaGraph 为例
"本文由社区用户 @阿七从第一视角讲述其团队重构图数据库的过程,首发于阿七公众号「浅谈架构」" 原文出处:https://mp.weixin.qq.com/s/WIJNq-nuuA ...
- TDengine 用户案例合集 | 智能环保项目的时序数据处理难点与优化实践
智能环保系统通常涉及大量的传感器和监测设备,以收集环境数据并对其进行分析和处理,这些数据通常是时序数据,即在一段时间内按时间顺序生成的数据,规模庞大且要求快速准确地进行分析和处理.也因此时序数据处理是 ...
- C++ bitset 用法和应用
C++的 bitset 在 bitset 头文件中,它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间. 下面是具体用法 构造函数 bitset常用构造函数有四种,如下 bi ...