mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 10:42:52 +08:00
- 优化 子查询的多表使用体验;
This commit is contained in:
parent
45bbe5f059
commit
e5b10704cc
@ -800,5 +800,14 @@
|
|||||||
<param name="that"></param>
|
<param name="that"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
|
||||||
|
<summary>
|
||||||
|
批量注入 Repository,可以参考代码自行调整
|
||||||
|
</summary>
|
||||||
|
<param name="services"></param>
|
||||||
|
<param name="globalDataFilter"></param>
|
||||||
|
<param name="assemblies"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
</doc>
|
</doc>
|
||||||
|
@ -342,5 +342,13 @@ namespace FreeSql.Tests.ClickHouse
|
|||||||
item = fsql.Select<Entity>().Where(a => a.Id == data2[1].Id).First();
|
item = fsql.Select<Entity>().Where(a => a.Id == data2[1].Id).First();
|
||||||
Assert.Equal(item.Content, json);
|
Assert.Equal(item.Content, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DbFirst()
|
||||||
|
{
|
||||||
|
var fsql = g.clickHouse;
|
||||||
|
var tbs = fsql.DbFirst.GetTablesByDatabase();
|
||||||
|
var tbs2 = fsql.DbFirst.GetTablesByDatabase("default");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,6 +9,78 @@ namespace FreeSql.Tests.SqlServer
|
|||||||
{
|
{
|
||||||
#region issues #1215
|
#region issues #1215
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void VicDemo20220815()
|
||||||
|
{
|
||||||
|
var fsql = g.sqlserver;
|
||||||
|
var subquery1 = fsql.Select<BaseHeadEntity>().AsType(typeof(BhEntity1)).Where(bh => bh.IsDeleted == false)
|
||||||
|
.FromQuery(fsql.Select<BaseItemEntity>().AsType(typeof(BiEntity1)).As("bi").Where(bi => bi.IsDeleted == false))
|
||||||
|
.InnerJoin(v => v.t1.Id == v.t2.HeadId)
|
||||||
|
.WithTempQuery(v => new
|
||||||
|
{
|
||||||
|
BillHead = v.t1,
|
||||||
|
Quantity = v.t2.Quantity,
|
||||||
|
RefQuantity = fsql.Select<BaseItemEntity>().AsType(typeof(BiEntity2)).As("bi2")
|
||||||
|
.Where(ti2 => ti2.RefHeadId == v.t2.HeadId && ti2.RefItemId == v.t2.Id)
|
||||||
|
.Sum(ti2 => ti2.Quantity),
|
||||||
|
})
|
||||||
|
.Where(v => v.RefQuantity < v.Quantity)
|
||||||
|
.GroupBy(v => v.BillHead.Id)
|
||||||
|
.ToSql(v => v.Key);
|
||||||
|
var sql1 = fsql.Select<BaseHeadEntity>().AsType(typeof(BhEntity1))
|
||||||
|
.Where($"a.Id IN ({subquery1})").OrderByDescending(vh => vh.Date)
|
||||||
|
.ToSql();
|
||||||
|
Assert.Equal(@"SELECT a.[IsDeleted], a.[Id], a.[No], a.[Date]
|
||||||
|
FROM [bhe_1] a
|
||||||
|
WHERE (a.Id IN (SELECT a.[Id] as1
|
||||||
|
FROM (
|
||||||
|
SELECT a.[IsDeleted], a.[Id], a.[No], a.[Date], SP10b.[Quantity], isnull((SELECT sum(ti2.[Quantity])
|
||||||
|
FROM [bie_2] ti2
|
||||||
|
WHERE (ti2.[RefHeadId] = SP10b.[HeadId] AND ti2.[RefItemId] = SP10b.[Id])), 0) [RefQuantity]
|
||||||
|
FROM [bhe_1] a
|
||||||
|
INNER JOIN (
|
||||||
|
SELECT bi.[IsDeleted], bi.[Id], bi.[HeadId], bi.[GoodsId], bi.[Quantity], bi.[RefHeadId], bi.[RefItemId]
|
||||||
|
FROM [bie_1] bi
|
||||||
|
WHERE (bi.[IsDeleted] = 0)) SP10b ON a.[Id] = SP10b.[HeadId]
|
||||||
|
WHERE (a.[IsDeleted] = 0) ) a
|
||||||
|
WHERE (a.[RefQuantity] < a.[Quantity])
|
||||||
|
GROUP BY a.[Id]))
|
||||||
|
ORDER BY a.[Date] DESC", sql1);
|
||||||
|
|
||||||
|
var sql2 = fsql.Select<BaseHeadEntity>().AsType(typeof(BhEntity1))
|
||||||
|
.Where(vh => fsql.Select<BaseHeadEntity>().AsType(typeof(BhEntity1)).Where(bh => bh.IsDeleted == false)
|
||||||
|
.FromQuery(fsql.Select<BaseItemEntity>().AsType(typeof(BiEntity1)).As("bi").Where(bi => bi.IsDeleted == false))
|
||||||
|
.InnerJoin(v => v.t1.Id == v.t2.HeadId)
|
||||||
|
.WithTempQuery(v => new
|
||||||
|
{
|
||||||
|
BillHead = v.t1,
|
||||||
|
Quantity = v.t2.Quantity,
|
||||||
|
RefQuantity = fsql.Select<BaseItemEntity>().AsType(typeof(BiEntity2)).As("bi2")
|
||||||
|
.Where(ti2 => ti2.RefHeadId == v.t2.HeadId && ti2.RefItemId == v.t2.Id)
|
||||||
|
.Sum(ti2 => ti2.Quantity),
|
||||||
|
})
|
||||||
|
.Where(v => v.RefQuantity < v.Quantity)
|
||||||
|
.Distinct()
|
||||||
|
.ToList(v => v.BillHead.Id).Contains(vh.Id)
|
||||||
|
).OrderByDescending(vh => vh.Date)
|
||||||
|
.ToSql();
|
||||||
|
Assert.Equal(@"SELECT a.[IsDeleted], a.[Id], a.[No], a.[Date]
|
||||||
|
FROM [bhe_1] a
|
||||||
|
WHERE (((a.[Id]) in (SELECT DISTINCT v.[Id]
|
||||||
|
FROM (
|
||||||
|
SELECT ht1.[IsDeleted], ht1.[Id], ht1.[No], ht1.[Date], ht2.[Quantity], isnull((SELECT sum(ti2.[Quantity])
|
||||||
|
FROM [bie_2] ti2
|
||||||
|
WHERE (ti2.[RefHeadId] = ht2.[HeadId] AND ti2.[RefItemId] = ht2.[Id])), 0) [RefQuantity]
|
||||||
|
FROM [BaseHeadEntity] ht1
|
||||||
|
INNER JOIN (
|
||||||
|
SELECT bi.[IsDeleted], bi.[Id], bi.[HeadId], bi.[GoodsId], bi.[Quantity], bi.[RefHeadId], bi.[RefItemId]
|
||||||
|
FROM [bie_1] bi
|
||||||
|
WHERE (bi.[IsDeleted] = 0)) ht2 ON ht1.[Id] = ht2.[HeadId]
|
||||||
|
WHERE (bh.[IsDeleted] = 0) ) v
|
||||||
|
WHERE (v.[RefQuantity] < v.[Quantity]))))
|
||||||
|
ORDER BY a.[Date] DESC", sql2);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void VicDemo20220813()
|
public void VicDemo20220813()
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ public class g
|
|||||||
{
|
{
|
||||||
static Lazy<IFreeSql> clickHouseLazy = new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
|
static Lazy<IFreeSql> clickHouseLazy = new Lazy<IFreeSql>(() => new FreeSql.FreeSqlBuilder()
|
||||||
.UseConnectionString(FreeSql.DataType.ClickHouse, "Compress=False;BufferSize=32768;SocketTimeout=10000;CheckCompressedHash=False;Encrypt=False;Compressor=lz4;Host=192.168.0.121;Port=8125;Database=PersonnelLocation;Username=root;Password=+riQ8V9D")
|
.UseConnectionString(FreeSql.DataType.ClickHouse, "Compress=False;BufferSize=32768;SocketTimeout=10000;CheckCompressedHash=False;Encrypt=False;Compressor=lz4;Host=192.168.0.121;Port=8125;Database=PersonnelLocation;Username=root;Password=+riQ8V9D")
|
||||||
|
.UseConnectionString(FreeSql.DataType.ClickHouse, "Compress=False;BufferSize=32768;SocketTimeout=10000;CheckCompressedHash=False;Encrypt=False;Compressor=lz4;Host=139.9.189.145;Port=1386;Database=default;Username=default;Password=Z2C2B4wR")
|
||||||
//.UseAutoSyncStructure(true)
|
//.UseAutoSyncStructure(true)
|
||||||
//.UseGenerateCommandParameterWithLambda(true)
|
//.UseGenerateCommandParameterWithLambda(true)
|
||||||
.UseMonitorCommand(
|
.UseMonitorCommand(
|
||||||
|
@ -1083,6 +1083,13 @@ namespace FreeSql.Internal
|
|||||||
case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})";
|
case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], tsc)})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (callType.FullName.StartsWith("FreeSql.ISelectGrouping`"))
|
||||||
|
{
|
||||||
|
switch (exp3.Method.Name)
|
||||||
|
{
|
||||||
|
case "ToList": return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
if (callType.FullName.StartsWith("FreeSql.ISelect`"))
|
if (callType.FullName.StartsWith("FreeSql.ISelect`"))
|
||||||
{ //子表查询
|
{ //子表查询
|
||||||
switch (exp3.Method.Name)
|
switch (exp3.Method.Name)
|
||||||
@ -1310,7 +1317,22 @@ namespace FreeSql.Internal
|
|||||||
if (_subSelectParentDiyMemExps.Value == null) _subSelectParentDiyMemExps.Value = new List<BaseDiyMemberExpression>();
|
if (_subSelectParentDiyMemExps.Value == null) _subSelectParentDiyMemExps.Value = new List<BaseDiyMemberExpression>();
|
||||||
_subSelectParentDiyMemExps.Value.Add(tsc.diymemexp);
|
_subSelectParentDiyMemExps.Value.Add(tsc.diymemexp);
|
||||||
}
|
}
|
||||||
|
switch (method.Name)
|
||||||
|
{
|
||||||
|
case nameof(ISelect<object>.From):
|
||||||
|
case nameof(ISelect<object>.FromQuery):
|
||||||
|
case nameof(ISelect<object>.WithTempQuery):
|
||||||
|
fsql = method.Invoke(fsql, args);
|
||||||
|
fsqlType = fsql.GetType();
|
||||||
|
fsqlSelect0 = fsql as Select0Provider;
|
||||||
|
if (tsc.dbParams != null) fsqlSelect0._params = tsc.dbParams;
|
||||||
|
fsqltables = fsqlSelect0._tables;
|
||||||
|
fsqltable1SetAlias = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
method.Invoke(fsql, args);
|
method.Invoke(fsql, args);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -1693,16 +1715,20 @@ namespace FreeSql.Internal
|
|||||||
return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
|
return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
|
||||||
}
|
}
|
||||||
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
|
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
|
||||||
if (tsc.diymemexp != null)
|
var diymemexps = new[] { tsc.diymemexp, tsc.subSelect001?._diymemexpWithTempQuery };
|
||||||
|
foreach (var diymemexp in diymemexps)
|
||||||
|
{
|
||||||
|
if (diymemexp != null)
|
||||||
{
|
{
|
||||||
var expStackFirst = expStack.First() as ParameterExpression;
|
var expStackFirst = expStack.First() as ParameterExpression;
|
||||||
var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value
|
var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value
|
||||||
var diyexpMembers = expStack.Where((a, b) => b >= bidx).ToArray();
|
var diyexpMembers = expStack.Where((a, b) => b >= bidx).ToArray();
|
||||||
if (diyexpMembers.Any() == false && tsc.diymemexp != null && tsc.diymemexp is Select0Provider.WithTempQueryParser tempQueryParser && tempQueryParser.GetOutsideSelectTable(expStackFirst) != null)
|
if (diyexpMembers.Any() == false && diymemexp != null && diymemexp is Select0Provider.WithTempQueryParser tempQueryParser && tempQueryParser.GetOutsideSelectTable(expStackFirst) != null)
|
||||||
diyexpMembers = expStack.ToArray();
|
diyexpMembers = expStack.ToArray();
|
||||||
var diyexpResult = tsc.diymemexp.ParseExp(diyexpMembers);
|
var diyexpResult = diymemexp.ParseExp(diyexpMembers);
|
||||||
if (string.IsNullOrEmpty(diyexpResult) == false) return diyexpResult;
|
if (string.IsNullOrEmpty(diyexpResult) == false) return diyexpResult;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var psgpdymes = _subSelectParentDiyMemExps.Value; //解决:分组之后的子查询解析
|
var psgpdymes = _subSelectParentDiyMemExps.Value; //解决:分组之后的子查询解析
|
||||||
if (psgpdymes?.Any() == true)
|
if (psgpdymes?.Any() == true)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +92,14 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
to._params = new List<DbParameter>(from._params.ToArray());
|
to._params = new List<DbParameter>(from._params.ToArray());
|
||||||
|
|
||||||
if (lambParms == null)
|
if (lambParms == null)
|
||||||
|
{
|
||||||
|
var fromTables = from._tables.Where(a => a.Type == SelectTableInfoType.Parent).ToList();
|
||||||
|
if (fromTables.Count > 0)
|
||||||
|
{
|
||||||
|
to._tables = new List<SelectTableInfo>(to._tables);
|
||||||
|
to._tables.AddRange(fromTables);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (to._tables.Count <= from._tables.Count)
|
if (to._tables.Count <= from._tables.Count)
|
||||||
to._tables = new List<SelectTableInfo>(from._tables.ToArray());
|
to._tables = new List<SelectTableInfo>(from._tables.ToArray());
|
||||||
@ -102,6 +110,7 @@ namespace FreeSql.Internal.CommonProvider
|
|||||||
to._tables[a] = from._tables[a];
|
to._tables[a] = from._tables[a];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var findedIndexs = new List<int>();
|
var findedIndexs = new List<int>();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user