diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs index ceda003c..b12a8cf3 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs @@ -914,6 +914,139 @@ GROUP BY a.[Nickname]"; Assert.Equal(11, list12[2].sum2); + var sql122 = fsql.Select() + .WithTempQuery(a => a) + .FromQuery(fsql.Select() + .Where(b => b.UserId > 0) + .GroupBy(b => b.UserId) + .WithTempQuery(b => new + { + b.Value.UserId, + sum1 = b.Sum(b.Value.UserId) + })) + .LeftJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Id > 0 && b.UserId > 0) + .ToSql((a, b) => new + { + a.Nickname, b.sum1, b.UserId, a.Id + }); + var assertSql122 = @"SELECT a.[Nickname] as1, b.[sum1] as2, b.[UserId] as3, a.[Id] as4 +FROM ( + SELECT a.[Id], a.[Nickname] + FROM [TwoTablePartitionBy_User] a ) a +LEFT JOIN ( + SELECT a.[UserId], sum(a.[UserId]) [sum1] + FROM [TwoTablePartitionBy_UserExt] a + WHERE (a.[UserId] > 0) + GROUP BY a.[UserId] ) b ON a.[Id] = b.[UserId] +WHERE (a.[Id] > 0 AND b.[UserId] > 0)"; + Assert.Equal(sql122, assertSql122); + var list122 = fsql.Select() + .WithTempQuery(a => a) + .FromQuery(fsql.Select() + .Where(b => b.UserId > 0) + .GroupBy(b => b.UserId) + .WithTempQuery(b => new + { + b.Value.UserId, + sum1 = b.Sum(b.Value.UserId) + })) + .LeftJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Id > 0 && b.UserId > 0) + .ToList((a, b) => new + { + a.Nickname, b.sum1, b.UserId, a.Id + }); + Assert.Equal(list122.Count, 6); + Assert.Equal("name01", list122[0].Nickname); + Assert.Equal(1, list122[0].sum1); + Assert.Equal(1, list122[0].UserId); + Assert.Equal(1, list122[0].Id); + Assert.Equal("name01", list122[1].Nickname); + Assert.Equal(2, list122[1].sum1); + Assert.Equal(2, list122[1].UserId); + Assert.Equal(2, list122[1].Id); + Assert.Equal("name01", list122[2].Nickname); + Assert.Equal(3, list122[2].sum1); + Assert.Equal(3, list122[2].UserId); + Assert.Equal(3, list122[2].Id); + Assert.Equal("name02", list122[3].Nickname); + Assert.Equal(4, list122[3].sum1); + Assert.Equal(4, list122[3].UserId); + Assert.Equal(4, list122[3].Id); + Assert.Equal("name03", list122[4].Nickname); + Assert.Equal(5, list122[4].sum1); + Assert.Equal(5, list122[4].UserId); + Assert.Equal(5, list122[4].Id); + Assert.Equal("name03", list122[5].Nickname); + Assert.Equal(6, list122[5].sum1); + Assert.Equal(6, list122[5].UserId); + Assert.Equal(6, list122[5].Id); + + + var sql123 = fsql.Select() + .FromQuery(fsql.Select() + .Where(b => b.UserId > 0) + .GroupBy(b => b.UserId) + .WithTempQuery(b => new + { + b.Value.UserId, + sum1 = b.Sum(b.Value.UserId) + })) + .LeftJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Id > 0 && b.UserId > 0) + .GroupBy((a, b) => new { a.Nickname }) + .ToSql(g => new + { + g.Key, + sum1 = g.Sum(g.Value.Item1.Id), + sum2 = g.Sum(g.Value.Item2.UserId), + sum3 = g.Sum(g.Value.Item2.sum1) + }); + var assertSql123 = @"SELECT a.[Nickname], sum(a.[Id]) as1, sum(b.[UserId]) as2, sum(b.[sum1]) as3 +FROM [TwoTablePartitionBy_User] a +LEFT JOIN ( + SELECT a.[UserId], sum(a.[UserId]) [sum1] + FROM [TwoTablePartitionBy_UserExt] a + WHERE (a.[UserId] > 0) + GROUP BY a.[UserId] ) b ON a.[Id] = b.[UserId] +WHERE (a.[Id] > 0 AND b.[UserId] > 0) +GROUP BY a.[Nickname]"; + Assert.Equal(sql123, assertSql123); + var list123 = fsql.Select() + .FromQuery(fsql.Select() + .Where(b => b.UserId > 0) + .GroupBy(b => b.UserId) + .WithTempQuery(b => new + { + b.Value.UserId, + sum1 = b.Sum(b.Value.UserId) + })) + .LeftJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Id > 0 && b.UserId > 0) + .GroupBy((a, b) => new { a.Nickname }) + .ToList(g => new + { + g.Key, + sum1 = g.Sum(g.Value.Item1.Id), + sum2 = g.Sum(g.Value.Item2.UserId), + sum3 = g.Sum(g.Value.Item2.sum1) + }); + Assert.Equal(list123.Count, 3); + Assert.Equal("name01", list123[0].Key.Nickname); + Assert.Equal(6, list123[0].sum1); + Assert.Equal(6, list123[0].sum2); + Assert.Equal(6, list123[0].sum3); + Assert.Equal("name02", list123[1].Key.Nickname); + Assert.Equal(4, list123[1].sum1); + Assert.Equal(4, list123[1].sum2); + Assert.Equal(4, list123[1].sum3); + Assert.Equal("name03", list123[2].Key.Nickname); + Assert.Equal(11, list123[2].sum1); + Assert.Equal(11, list123[2].sum2); + Assert.Equal(11, list123[2].sum3); + + var sql13 = fsql.Select().AsTable((_, old) => old.Replace("TwoTablePartitionBy_", "")) .FromQuery(fsql.Select().AsTable((_, old) => old.Replace("TwoTablePartitionBy_", "")) .Where(b => b.UserId > 0)) diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 645876d0..aeddf4fa 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -2207,6 +2207,8 @@ namespace FreeSql.Internal { if (node.Expression == _oldexp) return Expression.Property(_newexp, node.Member.Name); + if (node == _oldexp) + return _newexp; return base.VisitMember(node); } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 3fdedbe6..9f995254 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -155,8 +155,11 @@ namespace FreeSql.Internal.CommonProvider public List _outsideTable = new List(); public WithTempQueryParser(Select0Provider insideSelect, SelectGroupingProvider insideSelectGroup, Expression selector, SelectTableInfo outsideTable) { - _insideSelectList.Add(new InsideInfo(insideSelect, insideSelectGroup, selector)); - _outsideTable.Add(outsideTable); + if (selector != null) + { + _insideSelectList.Add(new InsideInfo(insideSelect, insideSelectGroup, selector)); + _outsideTable.Add(outsideTable); + } } public class InsideInfo { @@ -223,7 +226,7 @@ namespace FreeSql.Internal.CommonProvider ParseExpMapResult = read; return $"{ParseExpMatchedTable.Alias}.{read.DbNestedField}"; } - for (var a = 0; a < members.Length; a++) + for (var a = members[0] == ParseExpMatchedTable.Parameter ? 1 : 0; a < members.Length; a++) { read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); if (read == null) return null; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 16ea5963..07a10f2f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -141,6 +141,8 @@ namespace FreeSql.Internal.CommonProvider } else { + if (retsp._diymemexpWithTempQuery == null) + retsp._diymemexpWithTempQuery = new WithTempQueryParser(null, null, null, null).Append(select2, rettbs[1]); if (select2sp._tableRule != null && select2sp.IsDefaultSqlContent == true) { sql2 = select2sp._tableRule(select2sp._tables[0].Table.Type, null); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index a68ea8c7..aa2cc7bb 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -66,8 +66,10 @@ namespace FreeSql.Internal.CommonProvider } if (tempQueryParser._outsideTable.Contains(curtable)) { + var replaceMember = firstMember.Type == curtable.Parameter.Type ? firstMember : members[0]; + var replaceVistor = new CommonExpression.ReplaceVisitor(); for (var a = 0; a < members.Length; a++) - members[a] = new CommonExpression.ReplaceVisitor().Modify(members[a], firstMember, curtable.Parameter); + members[a] = replaceVistor.Modify(members[a], replaceMember, curtable.Parameter); var ret = _select._diymemexpWithTempQuery.ParseExp(members); ParseExpMapResult = _select._diymemexpWithTempQuery.ParseExpMapResult; return ret;