首页 > 其他分享 >喜闻乐见最新的ORM查询BUG,看看有没你关注的

喜闻乐见最新的ORM查询BUG,看看有没你关注的

时间:2023-11-03 15:58:57浏览次数:36  
标签:a3 Id a1 喜闻乐见 ORM a4 var TestEntity 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`)

革命尚未成功,同志仍须努力

标签:a3,Id,a1,喜闻乐见,ORM,a4,var,TestEntity,BUG
From: https://www.cnblogs.com/hubro/p/17807737.html

相关文章

  • 从FrameDebugger看Unity渲染
     Unity如何渲染一个3D+2D的游戏画面,今天通过FrameDebugger来看下Unity内置渲染管线的渲染策略, 后续再出一些URP渲染管线相关的文章。    Unity渲染场景的几个主要部分    Unity内置渲染管线是基于摄像机来进行渲染的,每个摄像机按照摄像机的渲染顺序来依次渲染,渲......
  • How to format lists in pandoc-generated docx documents?
    Sorry,thelistindentationsarecurrentlyhard-codedandcan'tbecustomized.Youcould,however,postprocessthedocxproducedbypandoc,changingthefilenumbering.xmlinthedocxcontainer.Oryoucouldmodifythesourcecodeandrecompile.Thes......
  • 如何让 WinDebug Preview 加载 Dotnet Core 的 SOS.dll 进行调试
    一、前言最近我在使用WinDebug进行系统调试,也是在学习《Net高级调试》这本书。以前听过WinDebug调试器,但是没有使用过,由于最近想起来了,就好好的研究一下,学习一下。初次接触,还是走了不少弯路,踩了不少坑。关于WinDebug最新版的安装方法,可以在“微软商店”里面,直接查询......
  • QCN9074 QCN9024|DR9074E Compatible with DR4019 Platform OpenWrt
    ExcitingNews:WallysWiFi6Card#DR9074ENowCompatiblewithDR4019Platform(WiFi5)andOpenWrtDriver-AGame-ChangerinWirelessTech!Wearethrilledtobringyousomeexcitingnews!OurWallysWiFi6DualBandCard#DR9074Ehasjusttakenagiant......
  • 用结构化思维解一切BUG(3):实际案例
    背景本文是系列文章《用结构化思维解一切BUG》的第3篇,也是最高潮篇!本系列文章主要介绍一种「无需掌握技术细节,只需结构化思维和常识即可解一切BUG的方法」。在前序文章《用结构化思维解一切BUG(1):核心思路》中,我介绍了本方法的核心思路,即,基于结构化的「假设树」,通过重复多次执行......
  • uniapp小程序所遇到的bug
    最近小程序添加好多条条框框的规矩比如1、登录的时候要弹出隐私规则的弹窗2、要使用的api涉及到隐私的一定要在隐私规则里配置,在微信公众平台的设置里,更新隐私规则3、.如果涉及到手机号登录的小程序,则需要有游客模式,就是不可以在登录的时候向用户获取手机号,要在具体功能的前面......
  • Docker desktop for win/windows Debug Mode: false/true | Trouble Shooting | diagn
    Eventually,usingthedocker-D-ldebugsettingfortheclientIhavefoundthelogoutputs(apparentlycurrentlytherearenodebuglevelmessagesimplementedasreported.docker-DinfoDebugModedocker-Dversiondocker-D-ldebugC:\Users\[u......
  • C#中无法将文件“obj\x86\Debug\BookShoopTuto.exe”复制到“bin\Debug\BookShoo
    因为任务多开了,数据无法写入也是因为这个去任务管理区删掉运行的项目就可以了(删掉BookShoopTuto) 参考博客——https://blog.csdn.net/nxg0916/article/details/126782186......
  • a-form 必填选像与v-if 组合时,出现的问题
    问题描述:a-form时,必填项与v-if出现冲突,切换之后,必填提示反而没取消 解决方案:1.用v-show替换v-if ,孙然必填提示没有错位,但是切换回来之后必填提示还在2.用v-if时,在后面加上key值,确保唯一 ......
  • 去除WinForm程序中的Devexpress弹窗
    去除WinForm程序中的Devexpress弹窗///<summary>///应用程序的主入口点。///</summary>[STAThread]staticvoidMain(){if(!CheckInstance()){Application.Exit();......