起因,想测试下查询语句的生成,按以下逻辑代码示例
var query = rep.GetLambdaQuery().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).Join((a, b) => a.a1 == b.TestEntityId);//第一次关联
var join2 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
.Join((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().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).Join(JoinType.InnerJoin, (a, b) => a.a1 == b.TestEntityId);
var query3 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
.Join(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().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).InnerJoin((a, b) => a.a1 == b.TestEntityId);
var query2 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
.InnerJoin((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().Take(100);
var query2 = query.WithTempQuery(b => new { a1 服务器托管网= b.Id, a2 = b.F_String });
var query3 = query2.FromQuery(db.Select()).InnerJoin((a, b) => a.a1 == b.TestEntityId);
var query4 = query3.WithTempQuery((a, b) => new { a3 = a.a1, a4 = b.Name }).FromQuery(db.Select()).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().Take(100);
var query2 = query.Select(b => new { a1 = b.Id, a2 = b.F_String });
var query3 = query2.InnerJoin((a, c) => a.a1 == c.TestEntityId);
var query4 = query3.Select((a, c) => new { a3 = a.a1, a4 = c.Name })
// .InnerJoin((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`)
革命尚未成功,同志仍须努力
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net