diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 537315e2..26522f10 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -800,5 +800,14 @@ + + + 批量注入 Repository,可以参考代码自行调整 + + + + + + diff --git a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs index cc5dc4c5..75fb4d82 100644 --- a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs +++ b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest1.cs @@ -342,5 +342,13 @@ namespace FreeSql.Tests.ClickHouse item = fsql.Select().Where(a => a.Id == data2[1].Id).First(); Assert.Equal(item.Content, json); } + + [Fact] + public void DbFirst() + { + var fsql = g.clickHouse; + var tbs = fsql.DbFirst.GetTablesByDatabase(); + var tbs2 = fsql.DbFirst.GetTablesByDatabase("default"); + } } } \ No newline at end of file diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs index c99789e1..bc003d3f 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs @@ -9,6 +9,78 @@ namespace FreeSql.Tests.SqlServer { #region issues #1215 + [Fact] + public void VicDemo20220815() + { + var fsql = g.sqlserver; + var subquery1 = fsql.Select().AsType(typeof(BhEntity1)).Where(bh => bh.IsDeleted == false) + .FromQuery(fsql.Select().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().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().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().AsType(typeof(BhEntity1)) + .Where(vh => fsql.Select().AsType(typeof(BhEntity1)).Where(bh => bh.IsDeleted == false) + .FromQuery(fsql.Select().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().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] public void VicDemo20220813() { diff --git a/FreeSql.Tests/FreeSql.Tests/g.cs b/FreeSql.Tests/FreeSql.Tests/g.cs index 9330048b..4db61756 100644 --- a/FreeSql.Tests/FreeSql.Tests/g.cs +++ b/FreeSql.Tests/FreeSql.Tests/g.cs @@ -9,6 +9,7 @@ public class g { static Lazy clickHouseLazy = new Lazy(() => 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=139.9.189.145;Port=1386;Database=default;Username=default;Password=Z2C2B4wR") //.UseAutoSyncStructure(true) //.UseGenerateCommandParameterWithLambda(true) .UseMonitorCommand( diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 76cb1182..52c52b6e 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1083,6 +1083,13 @@ namespace FreeSql.Internal 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`")) { //子表查询 switch (exp3.Method.Name) @@ -1310,7 +1317,22 @@ namespace FreeSql.Internal if (_subSelectParentDiyMemExps.Value == null) _subSelectParentDiyMemExps.Value = new List(); _subSelectParentDiyMemExps.Value.Add(tsc.diymemexp); } - method.Invoke(fsql, args); + switch (method.Name) + { + case nameof(ISelect.From): + case nameof(ISelect.FromQuery): + case nameof(ISelect.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); + break; + } } finally { @@ -1693,15 +1715,19 @@ namespace FreeSql.Internal return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); } if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); - if (tsc.diymemexp != null) + var diymemexps = new[] { tsc.diymemexp, tsc.subSelect001?._diymemexpWithTempQuery }; + foreach (var diymemexp in diymemexps) { - var expStackFirst = expStack.First() as ParameterExpression; - var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value - 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) - diyexpMembers = expStack.ToArray(); - var diyexpResult = tsc.diymemexp.ParseExp(diyexpMembers); - if (string.IsNullOrEmpty(diyexpResult) == false) return diyexpResult; + if (diymemexp != null) + { + var expStackFirst = expStack.First() as ParameterExpression; + var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value + var diyexpMembers = expStack.Where((a, b) => b >= bidx).ToArray(); + if (diyexpMembers.Any() == false && diymemexp != null && diymemexp is Select0Provider.WithTempQueryParser tempQueryParser && tempQueryParser.GetOutsideSelectTable(expStackFirst) != null) + diyexpMembers = expStack.ToArray(); + var diyexpResult = diymemexp.ParseExp(diyexpMembers); + if (string.IsNullOrEmpty(diyexpResult) == false) return diyexpResult; + } } var psgpdymes = _subSelectParentDiyMemExps.Value; //解决:分组之后的子查询解析 if (psgpdymes?.Any() == true) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 9f995254..060cf9a5 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -93,13 +93,22 @@ namespace FreeSql.Internal.CommonProvider if (lambParms == null) { - if (to._tables.Count <= from._tables.Count) - to._tables = new List(from._tables.ToArray()); - else + var fromTables = from._tables.Where(a => a.Type == SelectTableInfoType.Parent).ToList(); + if (fromTables.Count > 0) { to._tables = new List(to._tables); - for (var a = 0; a < from._tables.Count; a++) - to._tables[a] = from._tables[a]; + to._tables.AddRange(fromTables); + } + else + { + if (to._tables.Count <= from._tables.Count) + to._tables = new List(from._tables.ToArray()); + else + { + to._tables = new List(to._tables); + for (var a = 0; a < from._tables.Count; a++) + to._tables[a] = from._tables[a]; + } } } else