From 1ee6ecf16fd88e80f0b65bd1f48badd997e99233 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 25 Jul 2022 13:02:01 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20WithTempQuery=20+=20Fr?= =?UTF-8?q?omQuery=20=E5=B5=8C=E5=A5=97=E6=9F=A5=E8=AF=A2=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=9B#1192?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 219 +++++- Examples/base_entity/base_entity.csproj | 1 + Examples/base_entity/base_entity.xml | 10 + .../SelectedQueryProvider.cs | 8 +- FreeSql.DbContext/FreeSql.DbContext.xml | 9 - .../FreeSql.Tests/MySql/MySqlCodeFirstTest.cs | 17 + .../Curd/SqlServerSelectWithTempQueryTest.cs | 693 ++++++++++++++++++ FreeSql.Tests/FreeSql.Tests/UnitTest2.cs | 2 +- FreeSql/Extensions/FreeSqlGlobalExtensions.cs | 6 +- .../Extensions/LambadaExpressionExtensions.cs | 17 + FreeSql/FreeSql.csproj | 4 + FreeSql/FreeSql.xml | 16 + FreeSql/Interface/Curd/ISelect/ISelect1.cs | 40 +- FreeSql/Interface/Curd/ISelect/ISelect2`16.cs | 72 +- .../Interface/Curd/ISelect/ISelectGrouping.cs | 7 + FreeSql/Internal/CommonExpression.cs | 191 ++++- .../SelectProvider/Select0Provider.cs | 139 +++- .../SelectProvider/Select0ProviderReader.cs | 60 +- .../SelectProvider/Select1Provider.cs | 89 ++- .../SelectProvider/Select1Provider2`16.cs | 300 ++++++-- .../SelectProvider/SelectGroupingProvider.cs | 21 +- .../SelectProvider/T4Temp/ISelect2`16.tt | 4 + .../T4Temp/Select1Provider2`16.tt | 20 +- .../Internal/Model/ReadAnonymousTypeInfo.cs | 29 +- FreeSql/Internal/Model/TableInfo.cs | 12 + 25 files changed, 1778 insertions(+), 208 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 69f41eef..0975a45f 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -304,7 +304,7 @@ namespace base_entity .UseNoneCommandParameter(true) - .UseConnectionString(FreeSql.DataType.Sqlite, "data source=test1.db;max pool size=5") + .UseConnectionString(FreeSql.DataType.Sqlite, "data source=:memory:") //.UseSlave("data source=test1.db", "data source=test2.db", "data source=test3.db", "data source=test4.db") //.UseSlaveWeight(10, 1, 1, 5) @@ -312,7 +312,7 @@ namespace base_entity //.UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5") - .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=2") + //.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=2") //.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") @@ -345,6 +345,82 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var anysql01 = fsql.Select().Where(a => a.Roles.Any(b => b.Users.Any(c => c.UserName == "admin"))).ToSql(); + + var atimpl = fsql.CodeFirst.GetTableByEntity(typeof(AsTableLog)) + .AsTableImpl; + + atimpl.GetTableNameByColumnValue(DateTime.Parse("2023-7-1"), autoExpand: true); + + + fsql.Select() + .InnerJoin((a, b) => a.GroupId == b.Id) + .Where((a, b) => b.GroupName == "group1") + .WithTempQuery((a, b) => new + { + User = a, + GroupName = b.GroupName, + rownum = SqlExt.RowNumber().Over().PartitionBy(b.GroupName).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToList(); + + var sqlt1 = fsql.Select() + .ToSql(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }, FieldAliasOptions.AsProperty); + sqlt1 = fsql.Select() + .WithSql(sqlt1) + .Where("a.rownum = 1") + .ToSql(); + + var sqlt2 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(); + var sqlt22 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToList(); + var sqlt23 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToList(a => new + { + a.item, + a.rownum + }); + + var sqlt24 = fsql.Select() + .GroupBy(a => new { a.Nickname }) + .WithTempQuery(g => new + { + g.Key.Nickname, + sum1 = g.Sum(g.Value.Avatar.Length) + }) + .Where(a => a.Nickname != null) + .ToList(); + + + + Func getName = () => "xxx"; + fsql.GlobalFilter.Apply("fil1", a => a.Nickname == getName()); + var gnsql = fsql.Select().ToSql(); + Dictionary dic22 = new Dictionary(); dic22.Add("id", 1); dic22.Add("name", "xxxx"); @@ -1111,21 +1187,21 @@ namespace base_entity var ug1s2 = UserGroup.Select.Where(a => a.User1s.AsSelect().Any(b => b.Nickname == "x1")).Limit(10).ToList(); - var r1 = new Role(); - r1.Id = "管理员"; - await r1.SaveAsync(); + //var r1 = new Role(); + //r1.Id = "管理员"; + //await r1.SaveAsync(); - var r2 = new Role(); - r2.Id = "超级会员"; - await r2.SaveAsync(); + //var r2 = new Role(); + //r2.Id = "超级会员"; + //await r2.SaveAsync(); - var ru1 = new RoleUser1(); - ru1.User1Id = u1.Id; - ru1.RoleId = r1.Id; - await ru1.SaveAsync(); + //var ru1 = new RoleUser1(); + //ru1.User1Id = u1.Id; + //ru1.RoleId = r1.Id; + //await ru1.SaveAsync(); - ru1.RoleId = r2.Id; - await ru1.SaveAsync(); + //ru1.RoleId = r2.Id; + //await ru1.SaveAsync(); var u1roles = await User1.Select.IncludeMany(a => a.Roles).ToListAsync(); var u1roles2 = await User1.Select.Where(a => a.Roles.AsSelect().Any(b => b.Id == "xx")).ToListAsync(); @@ -1181,4 +1257,119 @@ namespace base_entity } } } + + [Table(Name = "t_user")] + public partial class User + { + [Column(IsPrimary = true)] + public string User_id { get; set; } + + [Column(IsNullable = false)] + public string UserName { get; set; } + + [Column(IsNullable = false)] + public string UserPassword { get; set; } + + public DateTime? CreateDate { get; set; } + + public DateTime? ModifyDate { get; set; } + + + #region 外键 => 导航属性,ManyToMany + + [Navigate(ManyToMany = typeof(user_role))] + public List Roles { get; set; } + + + #endregion + } + + [Table(Name = "t_role")] + public partial class Role + { + + [Column(IsPrimary = true)] + public int ID { get; set; } + + [Column(IsNullable = false)] + public string Rolename { get; set; } + + [Column(DbType = "NTEXT")] + public string Description { get; set; } + + #region 外键 => 导航属性,ManyToMany + /// + /// 关联的用户集合 + /// + [Navigate(ManyToMany = typeof(user_role))] + public List Users { get; set; } + /// + /// 关联的权限集合 + /// + [Navigate(ManyToMany = typeof(role_permission))] + public List Permissions { get; set; } + + #endregion + + + } + + [Table(Name = "t_permission")] + public partial class Permission + { + + [Column(IsPrimary = true)] + public int ID { get; set; } + public string PermissionName { get; set; } + + [Column(DbType = "NTEXT")] + public string Description { get; set; } + + + #region 外键 => 导航属性,ManyToMany + + [Navigate(ManyToMany = typeof(role_permission))] + public List Roles { get; set; } + + #endregion + } + + + [Table(Name = "user_role")] + public partial class user_role + { + [Column(IsPrimary = true)] + public string User_id { get; set; } + + [Column(IsPrimary = true)] + public int Role_id { get; set; } + + + #region 外键 => 导航属性,ManyToMany + [Navigate(nameof(User_id))] + public User user { get; set; } + [Navigate(nameof(Role_id))] + public Role role { get; set; } + + #endregion + } + + [Table(Name = "role_permission")] + public partial class role_permission + { + [Column(IsPrimary = true)] + public int Role_id { get; set; } + + [Column(IsPrimary = true)] + public int Permission_id { get; set; } + + + #region 外键 => 导航属性,ManyToMany + [Navigate(nameof(Role_id))] + public Role role { get; set; } + [Navigate(nameof(Permission_id))] + public Permission permission { get; set; } + #endregion + } + } diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index a7121e70..2892934a 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -20,6 +20,7 @@ + diff --git a/Examples/base_entity/base_entity.xml b/Examples/base_entity/base_entity.xml index c340101f..df43321f 100644 --- a/Examples/base_entity/base_entity.xml +++ b/Examples/base_entity/base_entity.xml @@ -79,6 +79,16 @@ 软删除 + + + 关联的用户集合 + + + + + 关联的权限集合 + + 角色表 diff --git a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs index 8bf40398..a76cb98d 100644 --- a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs +++ b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs @@ -73,13 +73,19 @@ namespace FreeSql.Internal.CommonProvider public override string ParseExp(Expression[] members) { - if (members.Any() == false) return _map.DbField; + ParseExpMapResult = null; + if (members.Any() == false) + { + ParseExpMapResult = _map; + return _map.DbField; + } var read = _map; for (var a = 0; a < members.Length; a++) { read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); if (read == null) return null; } + ParseExpMapResult = read; return read.DbField; } diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 537315e2..594fbad3 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -733,15 +733,6 @@ - - - 根据Assembly扫描所有继承IEntityTypeConfiguration<T>的配置类 - - - - - - 创建普通数据上下文档对象 diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs index 054d18c7..336ee6c4 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs @@ -11,6 +11,23 @@ namespace FreeSql.Tests.MySql { public class MySqlCodeFirstTest { + [Fact] + public void Test_Bool01() + { + var fsql = g.mysql; + var dt = fsql.Insert( + new[] { + new test_bool01 { id = Guid.NewGuid(), isdeleted = true}, + new test_bool01 { id = Guid.NewGuid(), isdeleted = false}, + }).ToDataTable(); + } + + class test_bool01 + { + public Guid id { get; set; } + public bool isdeleted { get; set; } + } + [Fact] public void Test_0String() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs new file mode 100644 index 00000000..d1fc0b52 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/Curd/SqlServerSelectWithTempQueryTest.cs @@ -0,0 +1,693 @@ +using FreeSql.DataAnnotations; +using System; +using System.Diagnostics; +using Xunit; + +namespace FreeSql.Tests.SqlServer +{ + public class SqlServerSelectWithTempQueryTest + { + [Fact] + public void SingleTablePartitionBy() + { + var fsql = g.sqlserver; + + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { + new SingleTablePartitionBy_User { Id = 1, Nickname = "name01" }, + new SingleTablePartitionBy_User { Id = 2, Nickname = "name01" }, + new SingleTablePartitionBy_User { Id = 3, Nickname = "name01" }, + new SingleTablePartitionBy_User { Id = 4, Nickname = "name02" }, + new SingleTablePartitionBy_User { Id = 5, Nickname = "name03" }, + new SingleTablePartitionBy_User { Id = 6, Nickname = "name03" }, + }).ExecuteAffrows(); + + var sql01 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(); + var assertSql01 = @"SELECT * +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [SingleTablePartitionBy_User] a ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql01, sql01); + + var sel01 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql01, sel01.ToSql()); + + var list01 = sel01.ToList(); + Assert.Equal(3, list01.Count); + Assert.Equal(list01[0].rownum, 1); + Assert.Equal(list01[0].item.Id, 1); + Assert.Equal(list01[0].item.Nickname, "name01"); + Assert.Equal(list01[1].rownum, 1); + Assert.Equal(list01[1].item.Id, 4); + Assert.Equal(list01[1].item.Nickname, "name02"); + Assert.Equal(list01[2].rownum, 1); + Assert.Equal(list01[2].item.Id, 5); + Assert.Equal(list01[2].item.Nickname, "name03"); + + + var sql02 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => a.item); + var assertSql02 = @"SELECT a.[Id] as1, a.[Nickname] as2 +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [SingleTablePartitionBy_User] a ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql02, sql02); + + var sel02 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql02, sel02.ToSql(a => a.item)); + + var list02 = sel02.ToList(a => a.item); + Assert.Equal(3, list02.Count); + Assert.Equal(list02[0].Id, 1); + Assert.Equal(list02[0].Nickname, "name01"); + Assert.Equal(list02[1].Id, 4); + Assert.Equal(list02[1].Nickname, "name02"); + Assert.Equal(list02[2].Id, 5); + Assert.Equal(list02[2].Nickname, "name03"); + + + var sql03 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => new + { + a.item.Id, + a.rownum + }); + var assertSql03 = @"SELECT a.[Id] as1, a.[rownum] as2 +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [SingleTablePartitionBy_User] a ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql03, sql03); + + var sel03 = fsql.Select() + .WithTempQuery(a => new + { + item = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql03, sel03.ToSql(a => new + { + a.item.Id, + a.rownum + })); + + var list03 = sel03.ToList(a => new + { + a.item.Id, + a.rownum + }); + Assert.Equal(3, list03.Count); + Assert.Equal(list03[0].rownum, 1); + Assert.Equal(list03[0].Id, 1); + Assert.Equal(list03[1].rownum, 1); + Assert.Equal(list03[1].Id, 4); + Assert.Equal(list03[2].rownum, 1); + Assert.Equal(list03[2].Id, 5); + + + + var sql04 = fsql.Select() + .WithTempQuery(a => new + { + a.Id, + a.Nickname, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => new SingleTablePartitionBy_UserDto()); + var assertSql04 = @"SELECT a.[Id] as1, a.[rownum] as2 +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [SingleTablePartitionBy_User] a ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql04, sql04); + + var sel04 = fsql.Select() + .WithTempQuery(a => new + { + a.Id, + a.Nickname, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql04, sel04.ToSql(a => new SingleTablePartitionBy_UserDto())); + + var list04 = sel04.ToList(); + Assert.Equal(3, list04.Count); + Assert.Equal(list04[0].rownum, 1); + Assert.Equal(list04[0].Id, 1); + Assert.Equal(list04[1].rownum, 1); + Assert.Equal(list04[1].Id, 4); + Assert.Equal(list04[2].rownum, 1); + Assert.Equal(list04[2].Id, 5); + } + class SingleTablePartitionBy_User + { + public int Id { get; set; } + public string Nickname { get; set; } + } + class SingleTablePartitionBy_UserDto + { + public int Id { get; set; } + public int rownum { get; set; } + } + + + [Fact] + public void TwoTablePartitionBy() + { + var fsql = g.sqlserver; + + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { + new TwoTablePartitionBy_User { Id = 1, Nickname = "name01" }, + new TwoTablePartitionBy_User { Id = 2, Nickname = "name01" }, + new TwoTablePartitionBy_User { Id = 3, Nickname = "name01" }, + new TwoTablePartitionBy_User { Id = 4, Nickname = "name02" }, + new TwoTablePartitionBy_User { Id = 5, Nickname = "name03" }, + new TwoTablePartitionBy_User { Id = 6, Nickname = "name03" }, + }).ExecuteAffrows(); + fsql.Insert(new[] { + new TwoTablePartitionBy_UserExt { UserId = 1, Remark = "remark01" }, + new TwoTablePartitionBy_UserExt { UserId = 2, Remark = "remark02" }, + new TwoTablePartitionBy_UserExt { UserId = 3, Remark = "remark03" }, + new TwoTablePartitionBy_UserExt { UserId = 4, Remark = "remark04" }, + new TwoTablePartitionBy_UserExt { UserId = 5, Remark = "remark05" }, + new TwoTablePartitionBy_UserExt { UserId = 6, Remark = "remark06" }, + }).ExecuteAffrows(); + + var sql01 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(); + var assertSql01 = @"SELECT * +FROM ( + SELECT a.[Id], a.[Nickname], b.[UserId], b.[Remark], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a + INNER JOIN [TwoTablePartitionBy_UserExt] b ON a.[Id] = b.[UserId] ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql01, sql01); + + var sel01 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql01, sel01.ToSql()); + + var list01 = sel01.ToList(); + Assert.Equal(3, list01.Count); + Assert.Equal(list01[0].rownum, 1); + Assert.Equal(list01[0].user.Id, 1); + Assert.Equal(list01[0].user.Nickname, "name01"); + Assert.Equal(list01[0].userext.Remark, "remark01"); + Assert.Equal(list01[1].rownum, 1); + Assert.Equal(list01[1].user.Id, 4); + Assert.Equal(list01[1].user.Nickname, "name02"); + Assert.Equal(list01[1].userext.Remark, "remark04"); + Assert.Equal(list01[2].rownum, 1); + Assert.Equal(list01[2].user.Id, 5); + Assert.Equal(list01[2].user.Nickname, "name03"); + Assert.Equal(list01[2].userext.Remark, "remark05"); + + + var sql02 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => a.user); + var assertSql02 = @"SELECT a.[Id] as1, a.[Nickname] as2 +FROM ( + SELECT a.[Id], a.[Nickname], b.[UserId], b.[Remark], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a + INNER JOIN [TwoTablePartitionBy_UserExt] b ON a.[Id] = b.[UserId] ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql02, sql02); + + var sel02 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql02, sel02.ToSql(a => a.user)); + + var list02 = sel02.ToList(a => a.user); + Assert.Equal(3, list02.Count); + Assert.Equal(list02[0].Id, 1); + Assert.Equal(list02[0].Nickname, "name01"); + Assert.Equal(list02[1].Id, 4); + Assert.Equal(list02[1].Nickname, "name02"); + Assert.Equal(list02[2].Id, 5); + Assert.Equal(list02[2].Nickname, "name03"); + + + var sql022 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => a.userext); + var assertSql022 = @"SELECT a.[UserId] as1, a.[Remark] as2 +FROM ( + SELECT a.[Id], a.[Nickname], b.[UserId], b.[Remark], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a + INNER JOIN [TwoTablePartitionBy_UserExt] b ON a.[Id] = b.[UserId] ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql022, sql022); + + var sel022 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql022, sel022.ToSql(a => a.userext)); + + var list022 = sel022.ToList(a => a.userext); + Assert.Equal(3, list022.Count); + Assert.Equal(list022[0].UserId, 1); + Assert.Equal(list022[0].Remark, "remark01"); + Assert.Equal(list022[1].UserId, 4); + Assert.Equal(list022[1].Remark, "remark04"); + Assert.Equal(list022[2].UserId, 5); + Assert.Equal(list022[2].Remark, "remark05"); + + + var sql03 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => new + { + a.user.Id, + a.rownum + }); + var assertSql03 = @"SELECT a.[Id] as1, a.[rownum] as2 +FROM ( + SELECT a.[Id], a.[Nickname], b.[UserId], b.[Remark], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a + INNER JOIN [TwoTablePartitionBy_UserExt] b ON a.[Id] = b.[UserId] ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql03, sql03); + + var sel03 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + user = a, + userext = b, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql03, sel03.ToSql(a => new + { + a.user.Id, + a.rownum + })); + + var list03 = sel03.ToList(a => new + { + a.user.Id, + a.rownum + }); + Assert.Equal(3, list03.Count); + Assert.Equal(list03[0].rownum, 1); + Assert.Equal(list03[0].Id, 1); + Assert.Equal(list03[1].rownum, 1); + Assert.Equal(list03[1].Id, 4); + Assert.Equal(list03[2].rownum, 1); + Assert.Equal(list03[2].Id, 5); + + + + var sql04 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + a.Id, + a.Nickname, + b.Remark, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .ToSql(a => new TwoTablePartitionBy_UserDto()); + var assertSql04 = @"SELECT a.[Id] as1, a.[rownum] as2, a.[Remark] as3 +FROM ( + SELECT a.[Id], a.[Nickname], b.[Remark], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a + INNER JOIN [TwoTablePartitionBy_UserExt] b ON a.[Id] = b.[UserId] ) a +WHERE (a.[rownum] = 1)"; + Assert.Equal(assertSql04, sql04); + + var sel04 = fsql.Select() + .InnerJoin((a, b) => a.Id == b.UserId) + .WithTempQuery((a, b) => new + { + a.Id, + a.Nickname, + b.Remark, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1); + Assert.Equal(assertSql04, sel04.ToSql(a => new TwoTablePartitionBy_UserDto())); + + var list04 = sel04.ToList(); + Assert.Equal(3, list04.Count); + Assert.Equal(list04[0].rownum, 1); + Assert.Equal(list04[0].Id, 1); + Assert.Equal(list04[0].remark, "remark01"); + Assert.Equal(list04[1].rownum, 1); + Assert.Equal(list04[1].Id, 4); + Assert.Equal(list04[1].remark, "remark04"); + Assert.Equal(list04[2].rownum, 1); + Assert.Equal(list04[2].Id, 5); + Assert.Equal(list04[2].remark, "remark05"); + + + var sql05 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .WithTempQuery(a => a.user) + .Where(a => a.Nickname == "name03") + .ToSql(a => new TwoTablePartitionBy_UserDto()); + var assertSql05 = @"SELECT a.[Id] as1 +FROM ( + SELECT a.[Id], a.[Nickname] + FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a ) a + WHERE (a.[rownum] = 1) ) a +WHERE (a.[Nickname] = N'name03')"; + Assert.Equal(sql05, assertSql05); + var list05 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .WithTempQuery(a => a.user) + .Where(a => a.Nickname == "name03") + .ToList(); + Assert.Equal(list05.Count, 1); + Assert.Equal(5, list05[0].Id); + Assert.Equal(0, list05[0].rownum); + Assert.Null(list05[0].remark); + + + var sql06 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .WithTempQuery(a => a.user) + .From() + .InnerJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Nickname == "name03" || a.Nickname == "name02") + .ToSql((a, b) => new TwoTablePartitionBy_UserDto()); + var assertSql06 = @"SELECT a.[Id] as1, b.[Remark] as2 +FROM ( + SELECT a.[Id], a.[Nickname] + FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a ) a + WHERE (a.[rownum] = 1) ) a +INNER JOIN [TwoTablePartitionBy_UserExt] b ON a.[Id] = b.[UserId] +WHERE ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))"; + Assert.Equal(sql06, assertSql06); + var list06 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .WithTempQuery(a => a.user) + .From() + .InnerJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Nickname == "name03" || a.Nickname == "name02") + .ToList(); + Assert.Equal(list06.Count, 2); + Assert.Equal(list06[0].rownum, 0); + Assert.Equal(list06[0].Id, 4); + Assert.Equal(list06[0].remark, "remark04"); + Assert.Equal(list06[1].rownum, 0); + Assert.Equal(list06[1].Id, 5); + Assert.Equal(list06[1].remark, "remark05"); + + + var sql07 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .WithTempQuery(a => a.user) + .FromQuery(fsql.Select()) + .InnerJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Nickname == "name03" || a.Nickname == "name02") + .ToSql((a, b) => new TwoTablePartitionBy_UserDto()); + var assertSql07 = @"SELECT a.[Id] as1, b.[Remark] as2 +FROM ( + SELECT a.[Id], a.[Nickname] + FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a ) a + WHERE (a.[rownum] = 1) ) a +INNER JOIN (SELECT a.[UserId], a.[Remark] + FROM [TwoTablePartitionBy_UserExt] a) b ON a.[Id] = b.[UserId] +WHERE ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))"; + Assert.Equal(sql07, assertSql07); + var list07 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .WithTempQuery(a => a.user) + .FromQuery(fsql.Select()) + .InnerJoin((a, b) => a.Id == b.UserId) + .Where((a, b) => a.Nickname == "name03" || a.Nickname == "name02") + .ToList(); + Assert.Equal(list07.Count, 2); + Assert.Equal(list07[0].rownum, 0); + Assert.Equal(list07[0].Id, 4); + Assert.Equal(list07[0].remark, "remark04"); + Assert.Equal(list07[1].rownum, 0); + Assert.Equal(list07[1].Id, 5); + Assert.Equal(list07[1].remark, "remark05"); + + + var sql08 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .FromQuery(fsql.Select().Where(b => b.UserId > 0)) + .InnerJoin((a, b) => a.user.Id == b.UserId) + .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02") + .ToSql((a, b) => new TwoTablePartitionBy_UserDto()); + var assertSql08 = @"SELECT a.[rownum] as1, b.[Remark] as2 +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a ) a +INNER JOIN (SELECT a.[UserId], a.[Remark] + FROM [TwoTablePartitionBy_UserExt] a + WHERE (a.[UserId] > 0)) b ON a.[Id] = b.[UserId] +WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))"; + Assert.Equal(sql08, assertSql08); + var list08 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .FromQuery(fsql.Select().Where(b => b.UserId > 0)) + .InnerJoin((a, b) => a.user.Id == b.UserId) + .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02") + .ToList(); + Assert.Equal(list08.Count, 2); + Assert.Equal(list08[0].rownum, 1); + Assert.Equal(list08[0].Id, 0); + Assert.Equal(list08[0].remark, "remark04"); + Assert.Equal(list08[1].rownum, 1); + Assert.Equal(list08[1].Id, 0); + Assert.Equal(list08[1].remark, "remark05"); + + + var sql09 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .FromQuery(fsql.Select().Where(b => b.UserId > 0).GroupBy(b => new { b.UserId, b.Remark }).WithTempQuery(b => b.Key)) + .InnerJoin((a, b) => a.user.Id == b.UserId) + .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02") + .ToSql((a, b) => new TwoTablePartitionBy_UserDto()); + var assertSql09 = @"SELECT a.[rownum] as1, b.[Remark] as2 +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a ) a +INNER JOIN ( SELECT a.[UserId], a.[Remark] + FROM [TwoTablePartitionBy_UserExt] a + WHERE (a.[UserId] > 0) + GROUP BY a.[UserId], a.[Remark] ) b ON a.[Id] = b.[UserId] +WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))"; + Assert.Equal(sql09, assertSql09); + var list09 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .FromQuery(fsql.Select().Where(b => b.UserId > 0).GroupBy(b => new { b.UserId, b.Remark }).WithTempQuery(b => b.Key)) + .InnerJoin((a, b) => a.user.Id == b.UserId) + .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02") + .ToList(); + Assert.Equal(list09.Count, 2); + Assert.Equal(list09[0].rownum, 1); + Assert.Equal(list09[0].Id, 0); + Assert.Equal(list09[0].remark, "remark04"); + Assert.Equal(list09[1].rownum, 1); + Assert.Equal(list09[1].Id, 0); + Assert.Equal(list09[1].remark, "remark05"); + + + var sql10 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .FromQuery(fsql.Select().Where(b => b.UserId > 0).GroupBy(b => new { b.UserId, b.Remark }).WithTempQuery(b => new { b.Key, rownum = b.Sum(b.Value.UserId) })) + .InnerJoin((a, b) => a.user.Id == b.Key.UserId) + .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02") + .ToSql((a, b) => new TwoTablePartitionBy_UserDto()); + var assertSql10 = @"SELECT a.[rownum] as1 +FROM ( + SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum] + FROM [TwoTablePartitionBy_User] a ) a +INNER JOIN ( SELECT a.[UserId], a.[Remark], sum(a.[UserId]) [rownum] + FROM [TwoTablePartitionBy_UserExt] a + WHERE (a.[UserId] > 0) + GROUP BY a.[UserId], a.[Remark] ) b ON a.[Id] = b.[UserId] +WHERE (a.[rownum] = 1) AND ((a.[Nickname] = N'name03' OR a.[Nickname] = N'name02'))"; + Assert.Equal(sql10, assertSql10); + var list10 = fsql.Select() + .WithTempQuery(a => new + { + user = a, + rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue() + }) + .Where(a => a.rownum == 1) + .FromQuery(fsql.Select().Where(b => b.UserId > 0).GroupBy(b => new { b.UserId, b.Remark }).WithTempQuery(b => new { b.Key, rownum = b.Sum(b.Value.UserId) })) + .InnerJoin((a, b) => a.user.Id == b.Key.UserId) + .Where((a, b) => a.user.Nickname == "name03" || a.user.Nickname == "name02") + .ToList(); + Assert.Equal(list10.Count, 2); + Assert.Equal(list10[0].rownum, 1); + Assert.Equal(list10[0].Id, 0); + Assert.Null(list10[0].remark); + Assert.Equal(list10[1].rownum, 1); + Assert.Equal(list10[1].Id, 0); + Assert.Null(list10[1].remark); + } + class TwoTablePartitionBy_User + { + public int Id { get; set; } + public string Nickname { get; set; } + } + class TwoTablePartitionBy_UserExt + { + public int UserId { get; set; } + public string Remark { get; set; } + } + class TwoTablePartitionBy_UserDto + { + public int Id { get; set; } + public int rownum { get; set; } + public string remark { get; set; } + } + } +} diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs index 6eec06d4..19a7dedf 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest2.cs @@ -532,7 +532,7 @@ namespace FreeSql.Tests }; - var dbs = g.sqlserver.DbFirst.GetDatabases(); + //var dbs = g.sqlserver.DbFirst.GetDatabases(); var tbs = g.sqlserver.DbFirst.GetTablesByDatabase("ds_shop"); var dicParamslist = g.sqlite.Select().Page(1, 10) diff --git a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs index b0c80547..2bfede75 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExtensions.cs @@ -703,10 +703,10 @@ JOIN {select._commonUtils.QuoteSqlName(tbDbName)} a ON cte_tbc.cte_id = a.{selec case DataType.OdbcSqlServer: case DataType.Firebird: case DataType.ClickHouse: - sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule, Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(string) }), pathSelector?.Body), null, null, null); + sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule, Expression.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(string) }), pathSelector?.Body), select._diymemexpWithTempQuery, null, null); break; default: - sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule, pathSelector?.Body, null, null, null); + sql1ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule, pathSelector?.Body, select._diymemexpWithTempQuery, null, null); break; } sql1ctePath = $"{sql1ctePath} as cte_path, "; @@ -724,7 +724,7 @@ JOIN {select._commonUtils.QuoteSqlName(tbDbName)} a ON cte_tbc.cte_id = a.{selec if (pathSelector != null) { select._tables[0].Parameter = pathSelector?.Parameters[0]; - var wct2ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule, pathSelector?.Body, null, null, null); + var wct2ctePath = select._commonExpression.ExpressionWhereLambda(select._tables, select._tableRule, pathSelector?.Body, select._diymemexpWithTempQuery, null, null); sql2ctePath = select._commonUtils.StringConcat( new string[] { up == false ? "wct1.cte_path" : wct2ctePath, diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 61a6eb5a..9f219194 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -233,6 +233,12 @@ namespace System.Linq.Expressions test.Visit(exp); return test.Result; } + public static ParameterExpression GetParameter(this Expression exp) + { + var test = new GetParameterExpressionVisitor(); + test.Visit(exp); + return test.Result; + } static ConcurrentDictionary> _dicTypeMethod = new ConcurrentDictionary>(); public static bool IsStringJoin(this MethodCallExpression exp, out Expression tolistObjectExpOut, out MethodInfo toListMethodOut, out LambdaExpression toListArgs0Out) @@ -357,4 +363,15 @@ namespace System.Linq.Expressions return node; } } + + internal class GetParameterExpressionVisitor : ExpressionVisitor + { + public ParameterExpression Result { get; private set; } + + protected override Expression VisitParameter(ParameterExpression node) + { + if (Result == null) Result = node; + return node; + } + } } \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 5f5cdac3..70ae9aaa 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -50,6 +50,10 @@ + + TextTemplatingFileGenerator + ISelect2`16.cs + TextTemplatingFileGenerator Select1Provider2`16.cs diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 9c673948..6cda4744 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2627,6 +2627,14 @@ 参数 + + + 嵌套查询 select * from ( select ... from table ... ) a + + + + + 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") @@ -2716,6 +2724,14 @@ 指定字段 + + + 嵌套查询 select * from ( select ... from table group by ... ) a + + + + + 查询向后偏移行数 diff --git a/FreeSql/Interface/Curd/ISelect/ISelect1.cs b/FreeSql/Interface/Curd/ISelect/ISelect1.cs index 8ad115cc..5442ad67 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect1.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect1.cs @@ -175,22 +175,24 @@ namespace FreeSql /// /// /// - ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; - ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class; - ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class; - ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class; + ISelect From(Expression, T2, ISelectFromExpression>> exp = null) where T2 : class; + ISelect From(Expression, T2, T3, ISelectFromExpression>> exp = null) where T2 : class where T3 : class; + ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class; + ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class; - ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class; + ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class; + + ISelect FromQuery(ISelect select2) where T2 : class; /// /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") @@ -367,5 +369,13 @@ namespace FreeSql /// 参数 /// ISelect WithSql(string sql, object parms = null); + + /// + /// 嵌套查询 select * from ( select ... from table ... ) a + /// + /// + /// + /// + ISelect WithTempQuery(Expression> selector); } } \ No newline at end of file diff --git a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs index 4cd64f36..79183225 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelect2`16.cs @@ -1,4 +1,5 @@ -using FreeSql.Internal.Model; + +using FreeSql.Internal.Model; using System; using System.Collections.Generic; using System.Data; @@ -9,6 +10,13 @@ using System.Threading.Tasks; namespace FreeSql { + + + + + + + public interface ISelect : ISelect0, T1> where T2 : class { @@ -83,6 +91,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -113,6 +123,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -195,6 +207,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -225,6 +239,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -307,6 +323,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -337,6 +355,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -419,6 +439,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -449,6 +471,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -531,6 +555,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -561,6 +587,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -643,6 +671,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -673,6 +703,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -755,6 +787,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -785,6 +819,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -867,6 +903,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -897,6 +935,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -979,6 +1019,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1009,6 +1051,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -1091,6 +1135,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1121,6 +1167,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -1203,6 +1251,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1233,6 +1283,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -1315,6 +1367,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1345,6 +1399,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -1427,6 +1483,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1457,6 +1515,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -1539,6 +1599,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1569,6 +1631,8 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } @@ -1651,6 +1715,8 @@ namespace FreeSql ISelect WithSql(string sqlT1, string sqlT2, string sqlT3, string sqlT4, string sqlT5, string sqlT6, string sqlT7, string sqlT8, string sqlT9, string sqlT10, string sqlT11, string sqlT12, string sqlT13, string sqlT14, string sqlT15, string sqlT16, object parms = null); + ISelect WithTempQuery(Expression> selector); + #region HzyTuple 元组 bool Any(Expression, bool>> exp); @@ -1681,8 +1747,12 @@ namespace FreeSql ISelect OrderByDescending(Expression, TMember>> column); ISelect OrderByIf(bool condition, Expression, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression, TDto>> selector); + #endregion } } + + diff --git a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs index 3f081a79..286aee94 100644 --- a/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs +++ b/FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs @@ -75,6 +75,13 @@ namespace FreeSql /// string ToSql(string field); + /// + /// 嵌套查询 select * from ( select ... from table group by ... ) a + /// + /// + /// + /// + ISelect WithTempQuery(Expression, TDto>> selector); /// /// 查询向后偏移行数 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 7a69e81a..b24dcec0 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -25,6 +25,7 @@ namespace FreeSql.Internal public ParameterExpression _lambdaParameter; public ReadAnonymousTypeInfo _map; public string _field; + public ReadAnonymousTypeInfo ParseExpMapResult { get; protected set; } public abstract string ParseExp(Expression[] members); } @@ -50,6 +51,23 @@ namespace FreeSql.Internal public bool ReadAnonymousField(List _tables, Func _tableRule, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, BaseDiyMemberExpression diymemexp, List whereGlobalFilter, List findIncludeMany, List findSubSelectMany, bool isAllDtoMap) { + void LocalSetFieldAlias(ref int localIndex) + { + if (localIndex >= 0) + { + parent.DbNestedField = $"as{++localIndex}"; + field.Append(_common.FieldAsAlias(parent.DbNestedField)); + } + else if (diymemexp?.ParseExpMapResult != null) + parent.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField; + else if (string.IsNullOrEmpty(parent.CsName) == false) + { + parent.DbNestedField = GetFieldAsCsName(parent.CsName); + if (localIndex == ReadAnonymousFieldAsCsName && parent.DbField.EndsWith(parent.DbNestedField, StringComparison.CurrentCultureIgnoreCase) == false) //DbField 和 CsName 相同的时候,不处理 + field.Append(_common.FieldAsAlias(parent.DbNestedField)); + } + } + Func getTSC = () => new ExpTSC { _tables = _tables, _tableRule = _tableRule, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决 switch (exp.NodeType) { @@ -59,8 +77,7 @@ namespace FreeSql.Internal case ExpressionType.NegateChecked: parent.DbField = $"-({ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, getTSC())})"; field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(GetFieldAsCsName(parent.CsName))); + LocalSetFieldAlias(ref index); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; case ExpressionType.Convert: return ReadAnonymousField(_tables, _tableRule, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap); @@ -79,8 +96,7 @@ namespace FreeSql.Internal else parent.DbField = _common.FormatSql("{0}", constExp?.Value); field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(GetFieldAsCsName(parent.CsName))); + LocalSetFieldAlias(ref index); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; case ExpressionType.Conditional: @@ -109,13 +125,12 @@ namespace FreeSql.Internal else parent.DbField = ExpressionLambdaToSql(exp, getTSC()); field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(GetFieldAsCsName(parent.CsName))); + LocalSetFieldAlias(ref index); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; case ExpressionType.Parameter: case ExpressionType.MemberAccess: - if (_common.GetTableByEntity(exp.Type) != null && + if ((_common.GetTableByEntity(exp.Type) != null || exp.Type.IsAnonymousType() && diymemexp != null) && //判断 [JsonMap] 并非导航对象 (exp.NodeType == ExpressionType.Parameter || exp is MemberExpression expMem && ( _common.GetTableByEntity(expMem.Expression.Type)?.ColumnsByCs.ContainsKey(expMem.Member.Name) == false || @@ -126,6 +141,28 @@ namespace FreeSql.Internal //加载表所有字段 var map = new List(); ExpressionSelectColumn_MemberAccess(_tables, _tableRule, map, SelectTableInfoType.From, exp, true, diymemexp); + if (map.Any() == false) + { + if (diymemexp != null && diymemexp.ParseExpMapResult != null) + { + var withTempQueryParser = diymemexp as Select0Provider.WithTempQueryParser; + diymemexp.ParseExpMapResult.CopyTo(parent); + foreach (var child in parent.GetAllChilds()) + { + if (withTempQueryParser != null) + field.Append(", ").Append(withTempQueryParser.ParseExpMatchedTable.Alias).Append(".").Append(child.DbNestedField); + else + field.Append(", ").Append(child.DbField); + if (index >= 0) + { + child.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(child.DbNestedField)); + } + } + return false; + } + throw new Exception($"未能加载它的所有成员,不支持解析表达式树 {exp}"); + } var tb = parent.Table = map.First().Table.Table; parent.CsType = tb.Type; parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst(); @@ -137,14 +174,19 @@ namespace FreeSql.Internal Property = tb.Properties.TryGetValue(map[idx].Column.CsName, out var tryprop) ? tryprop : tb.Type.GetProperty(map[idx].Column.CsName, BindingFlags.Public | BindingFlags.Instance), CsName = map[idx].Column.CsName, DbField = $"{map[idx].Table.Alias}.{_common.QuoteSqlName(map[idx].Column.Attribute.Name)}", + DbNestedField = _common.QuoteSqlName(map[idx].Column.Attribute.Name), CsType = map[idx].Column.CsType, MapType = map[idx].Column.Attribute.MapType }; field.Append(", ").Append(_common.RereadColumn(map[idx].Column, child.DbField)); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + if (index >= 0) + { + child.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(child.DbNestedField)); + } parent.Childs.Add(child); } - if (_tables.Count > 1) + if (_tables?.Count > 1) { //如果下级导航属性被 Include 过,则将他们也查询出来 foreach (var memProp in tb.Properties.Values) { @@ -199,15 +241,19 @@ namespace FreeSql.Internal } if (diymemexp != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) { - field.Append(diymemexp._field); + field.Append(diymemexp._field); if (diymemexp._map.Childs.Any() == false) //处理 GroupBy(a => a.Title) ToSql(g => new { tit = a.Key }, FieldAliasOptions.AsProperty) 问题 { - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName) + if (index >= 0) { - var csname = GetFieldAsCsName(parent.CsName); - if (diymemexp._field.EndsWith(csname, StringComparison.CurrentCultureIgnoreCase) == false) //DbField 和 CsName 相同的时候,不处理 - field.Append(_common.FieldAsAlias(csname)); + parent.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(parent.DbNestedField)); + } + else if (string.IsNullOrEmpty(parent.CsName) == false) + { + parent.DbNestedField = GetFieldAsCsName(parent.CsName); + if (index == ReadAnonymousFieldAsCsName && diymemexp._field.EndsWith(parent.DbNestedField, StringComparison.CurrentCultureIgnoreCase) == false) //DbField 和 CsName 相同的时候,不处理 + field.Append(_common.FieldAsAlias(parent.DbNestedField)); } } var parentProp = parent.Property; @@ -217,20 +263,14 @@ namespace FreeSql.Internal } if (parent.CsType == null) parent.CsType = exp.Type; var pdbfield = parent.DbField = ExpressionLambdaToSql(exp, getTSC()); - if (parent.MapType == null || _tables?.Any(a => a.Table.IsRereadSql) == true) + if (parent.MapType == null || _tables?.Any(a => a.Table?.IsRereadSql == true) == true) { var findcol = SearchColumnByField(_tables, null, parent.DbField); if (parent.MapType == null) parent.MapType = findcol?.Attribute.MapType ?? exp.Type; if (findcol != null) pdbfield = _common.RereadColumn(findcol, pdbfield); } field.Append(", ").Append(pdbfield); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) - { - var csname = GetFieldAsCsName(parent.CsName); - if (parent.DbField.EndsWith(csname, StringComparison.CurrentCultureIgnoreCase) == false) //DbField 和 CsName 相同的时候,不处理 - field.Append(_common.FieldAsAlias(csname)); - } + LocalSetFieldAlias(ref index); return false; } return false; @@ -263,7 +303,34 @@ namespace FreeSql.Internal { foreach (var dtTb in _tables) { - if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; + if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) + { + if (diymemexp != null && dtTb.Parameter != null && dtTb.Parameter.Type.GetPropertiesDictIgnoreCase().TryGetValue(dtoProp.Name, out var dtTbProp)) + { + var dbfield = diymemexp.ParseExp(new Expression[] { Expression.MakeMemberAccess(dtTb.Parameter, dtTbProp) }); + if (diymemexp.ParseExpMapResult != null) + { + var diychild = new ReadAnonymousTypeInfo + { + Property = dtoProp, + CsName = dtoProp.Name, + CsType = dtTbProp.PropertyType, + MapType = dtTbProp.PropertyType + }; + parent.Childs.Add(diychild); + diychild.DbField = $"{dtTb.Alias}.{diymemexp.ParseExpMapResult.DbNestedField}"; + diychild.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField; + field.Append(", ").Append(diychild.DbField); + if (index >= 0) + { + diychild.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(diychild.DbNestedField)); + } + break; + } + } + continue; + } if (trydtocol.Attribute.IsIgnore == true) continue; if (dicBindings?.ContainsKey(dtoProp.Name) == true) continue; @@ -280,8 +347,13 @@ namespace FreeSql.Internal else { child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; + child.DbNestedField = _common.QuoteSqlName(trydtocol.Attribute.Name); field.Append(", ").Append(_common.RereadColumn(trydtocol, child.DbField)); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + if (index >= 0) + { + child.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(child.DbNestedField)); + } } break; } @@ -328,15 +400,18 @@ namespace FreeSql.Internal //处理构造参数 for (var a = 0; a < newExp.Arguments.Count; a++) { + var csname = newExp.Members != null ? newExp.Members[a].Name : (newExp.Arguments[a] as MemberExpression)?.Member.Name; var child = new ReadAnonymousTypeInfo { Property = null, - CsName = newExp.Members != null ? newExp.Members[a].Name : (newExp.Arguments[a] as MemberExpression)?.Member.Name, + CsName = csname, CsType = newExp.Arguments[a].Type, MapType = newExp.Arguments[a].Type }; parent.Childs.Add(child); ReadAnonymousField(_tables, _tableRule, field, child, ref index, newExp.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, false); + if (child.CsName == null) + child.CsName = csname; } } else @@ -348,7 +423,34 @@ namespace FreeSql.Internal { foreach (var dtTb in _tables) { - if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) continue; + if (dtTb.Table.ColumnsByCs.TryGetValue(dtoProp.Name, out var trydtocol) == false) + { + if (diymemexp != null && dtTb.Parameter != null && dtTb.Parameter.Type.GetPropertiesDictIgnoreCase().TryGetValue(dtoProp.Name, out var dtTbProp)) + { + var dbfield = diymemexp.ParseExp(new Expression[] { Expression.MakeMemberAccess(dtTb.Parameter, dtTbProp) }); + if (diymemexp.ParseExpMapResult != null) + { + var diychild = new ReadAnonymousTypeInfo + { + Property = dtoProp, + CsName = dtoProp.Name, + CsType = dtTbProp.PropertyType, + MapType = dtTbProp.PropertyType + }; + parent.Childs.Add(diychild); + diychild.DbField = $"{dtTb.Alias}.{diymemexp.ParseExpMapResult.DbNestedField}"; + diychild.DbNestedField = diymemexp.ParseExpMapResult.DbNestedField; + field.Append(", ").Append(diychild.DbField); + if (index >= 0) + { + diychild.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(diychild.DbNestedField)); + } + break; + } + } + continue; + } if (trydtocol.Attribute.IsIgnore == true) continue; var child = new ReadAnonymousTypeInfo @@ -364,8 +466,13 @@ namespace FreeSql.Internal else { child.DbField = _common.RereadColumn(trydtocol, $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"); + child.DbNestedField = _common.QuoteSqlName(trydtocol.Attribute.Name); field.Append(", ").Append(child.DbField); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); + if (index >= 0) + { + child.DbNestedField = $"as{++index}"; + field.Append(_common.FieldAsAlias(child.DbNestedField)); + } } break; } @@ -376,8 +483,7 @@ namespace FreeSql.Internal } parent.DbField = $"({ExpressionLambdaToSql(exp, getTSC())})"; field.Append(", ").Append(parent.DbField); - if (index >= 0) field.Append(_common.FieldAsAlias($"as{++index}")); - else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(GetFieldAsCsName(parent.CsName))); + LocalSetFieldAlias(ref index); if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type; return false; } @@ -458,8 +564,8 @@ namespace FreeSql.Internal var testCol = _common.TrimQuoteSqlName(field).Split(new[] { '.' }, 2); if (testCol.Length == 2) { - var testTb = _tables.Where(a => a.Alias == testCol[0]).ToArray(); - if (testTb.Length == 1 && testTb[0].Table.Columns.TryGetValue(testCol[1], out var trytstcol)) + var testTb = _tables.Where(a => a.Table != null && a.Alias == testCol[0]).ToArray(); + if (testTb.Length == 1 && testTb[0].Table.Columns.TryGetValue(testCol[1], out var trytstcol) == true) return trytstcol; } } @@ -530,6 +636,12 @@ namespace FreeSql.Internal public string ExpressionWhereLambda(List _tables, Func _tableRule, Expression exp, BaseDiyMemberExpression diymemexp, List whereGlobalFilter, List dbParams) { + if (_tables?.Count > 1) + { + foreach (var tb in _tables) + if (tb.Parameter != null && tb.AliasInit.StartsWith("SP10")) + tb.Alias = tb.Parameter.Name; + } var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _tableRule = _tableRule, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = dbParams }); return GetBoolString(exp, sql); } @@ -537,6 +649,12 @@ namespace FreeSql.Internal public void ExpressionJoinLambda(List _tables, Func _tableRule, SelectTableInfoType tbtype, Expression exp, BaseDiyMemberExpression diymemexp, List whereGlobalFilter) { var tbidx = _tables.Count; + if (tbidx > 1) + { + foreach (var tb in _tables) + if (tb.Parameter != null && tb.AliasInit.StartsWith("SP10")) + tb.Alias = tb.Parameter.Name; + } var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _tableRule = _tableRule, diymemexp = diymemexp, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter }); sql = GetBoolString(exp, sql); @@ -777,6 +895,7 @@ namespace FreeSql.Internal return $"not({ExpressionLambdaToSql(notExp, tsc)})"; case ExpressionType.Quote: return ExpressionLambdaToSql((exp as UnaryExpression)?.Operand, tsc); case ExpressionType.Lambda: return ExpressionLambdaToSql((exp as LambdaExpression)?.Body, tsc); + case ExpressionType.Invoke: return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); case ExpressionType.TypeAs: case ExpressionType.Convert: case ExpressionType.ConvertChecked: @@ -1563,8 +1682,8 @@ namespace FreeSql.Internal { var expStackFirst = expStack.First(); var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value - var expText = tsc.diymemexp.ParseExp(expStack.Where((a, b) => b >= bidx).ToArray()); - if (string.IsNullOrEmpty(expText) == false) return expText; + var diyexpResult = tsc.diymemexp.ParseExp(expStack.Where((a, b) => b >= bidx).ToArray()); + if (string.IsNullOrEmpty(diyexpResult) == false) return diyexpResult; } var psgpdymes = _subSelectParentDiyMemExps.Value; //解决:分组之后的子查询解析 if (psgpdymes?.Any() == true) @@ -1572,8 +1691,8 @@ namespace FreeSql.Internal var expStackFirst = expStack.First(); if (expStackFirst.NodeType == ExpressionType.Parameter) { - var expText = psgpdymes.Where(a => a._lambdaParameter == expStackFirst).FirstOrDefault()?.ParseExp(expStack.Where((a, b) => b >= 2).ToArray()); - if (string.IsNullOrEmpty(expText) == false) return expText; + var diyexpResult = psgpdymes.Where(a => a._lambdaParameter == expStackFirst).FirstOrDefault()?.ParseExp(expStack.Where((a, b) => b >= 2).ToArray()); + if (string.IsNullOrEmpty(diyexpResult) == false) return diyexpResult; } } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 4e16ec18..22b11b9a 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -46,6 +46,11 @@ namespace FreeSql.Internal.CommonProvider public List _whereGlobalFilter; public Func _cancel; public bool _is_AsTreeCte; + public BaseDiyMemberExpression _diymemexpWithTempQuery; + + public bool IsDefaultSqlContent => _distinct == false && _is_AsTreeCte == false && _tables.Count == 1 && _where.Length == 0 && _join.Length == 0 && + string.IsNullOrWhiteSpace(_orderby) && string.IsNullOrWhiteSpace(_groupby) && string.IsNullOrWhiteSpace(_tosqlAppendContent) && + _aliasRule == null && _selectExpression == null; public Select0Provider() { @@ -71,6 +76,7 @@ namespace FreeSql.Internal.CommonProvider _selectExpression = null; _whereGlobalFilter?.Clear(); _cancel = null; + _diymemexpWithTempQuery = null; } public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) @@ -86,7 +92,16 @@ namespace FreeSql.Internal.CommonProvider to._params = new List(from._params.ToArray()); if (lambParms == null) - to._tables = new List(from._tables.ToArray()); + { + 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 { var findedIndexs = new List(); @@ -131,6 +146,95 @@ namespace FreeSql.Internal.CommonProvider to._whereGlobalFilter = new List(from._whereGlobalFilter.ToArray()); to._cancel = from._cancel; to._is_AsTreeCte = from._is_AsTreeCte; + to._diymemexpWithTempQuery = from._diymemexpWithTempQuery; + } + + internal class WithTempQueryParser : BaseDiyMemberExpression + { + public List _insideSelectList = new List(); + 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); + } + public class InsideInfo + { + public Select0Provider InsideSelect { get; } + public SelectGroupingProvider InsideSelectGroup { get; } + public CommonExpression InsideComonExp; + public string InsideField { get; } + public ReadAnonymousTypeAfInfo InsideAf { get; } + public ReadAnonymousTypeInfo InsideMap { get; } + + public InsideInfo(Select0Provider insideSelect, SelectGroupingProvider insideSelectGroup, Expression selector) + { + InsideSelect = insideSelect; + InsideSelectGroup = insideSelectGroup; + + InsideMap = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = CommonExpression.ReadAnonymousFieldAsCsName; //AsProperty + + if (selector != null) + { + if (insideSelectGroup != null) + InsideSelect._commonExpression.ReadAnonymousField(null, insideSelect._tableRule, field, InsideMap, ref index, selector, insideSelect, InsideSelectGroup, null, null, null, false); + else if (insideSelect != null) + InsideSelect._commonExpression.ReadAnonymousField(insideSelect._tables, InsideSelect._tableRule, field, InsideMap, ref index, selector, null, insideSelect._diymemexpWithTempQuery, insideSelect._whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany + } + InsideField = field.Length > 0 ? field.Remove(0, 2).ToString() : null; + InsideAf = new ReadAnonymousTypeAfInfo(InsideMap, "*"); + } + } + + public WithTempQueryParser Append(ISelect select, SelectTableInfo outsideTable) + { + if (outsideTable != null && (select as Select0Provider)?._diymemexpWithTempQuery is WithTempQueryParser withTempQuery) + { + _insideSelectList.Add(withTempQuery._insideSelectList[0]); + _outsideTable.Add(outsideTable); + } + return this; + } + + public SelectTableInfo ParseExpMatchedTable { get; private set; } + public override string ParseExp(Expression[] members) + { + ParseExpMapResult = null; + ParseExpMatchedTable = GetOutsideSelectTable(members.FirstOrDefault()?.GetParameter()); + var insideIndex = _outsideTable.FindIndex(a => a == ParseExpMatchedTable); + if (insideIndex == -1) + { + ParseExpMatchedTable = null; + return null; + } + var insideData = _insideSelectList[insideIndex]; + if (members.Any() == false) + { + ParseExpMapResult = insideData.InsideMap; + return $"{ParseExpMatchedTable.Alias}.{insideData.InsideMap.DbNestedField}"; + } + var read = insideData.InsideMap; + for (var a = 0; a < members.Length; a++) + { + read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); + if (read == null) return null; + } + ParseExpMapResult = read; + return $"{ParseExpMatchedTable.Alias}.{read.DbNestedField}"; + } + public SelectTableInfo GetOutsideSelectTable(ParameterExpression parameterExp) + { + if (parameterExp == null) return _outsideTable[0]; + var find = _outsideTable.Where(a => a.Parameter == parameterExp).ToArray(); + if (find.Length == 1) return find[0]; + find = _outsideTable.Where(a => a.Table.Type == parameterExp.Type).ToArray(); + if (find.Length == 1) return find[0]; + find = _outsideTable.Where(a => a.Alias == parameterExp.Name).ToArray(); + if (find.Length == 1) return find[0]; + return _outsideTable[0]; + } } public Expression ConvertStringPropertyToExpression(string property, bool fromFirstTable = false) @@ -276,7 +380,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, newexp, this, null, _whereGlobalFilter, null, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, newexp, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, true); return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); } public string GetNestSelectSql(Expression select, string affield, Func ToSql) @@ -762,6 +866,18 @@ namespace FreeSql.Internal.CommonProvider } public TSelect AsTable(Func tableRule) { + if (_tableRules.Count == 1 && _diymemexpWithTempQuery != null && _diymemexpWithTempQuery is WithTempQueryParser tempQueryParser) + { + var oldTableRule = _tableRules[0]; + var newTableRule = tableRule; + _tableRules.Clear(); + tableRule = (type, old) => + { + var tbname = newTableRule(type, null); + if (tbname != null) return tbname; + return oldTableRule(type, old); + }; + } if (tableRule != null) _tableRules.Add(tableRule); return this as TSelect; } @@ -796,7 +912,7 @@ namespace FreeSql.Internal.CommonProvider if (condition == false) return this as TSelect; Expression exp = ConvertStringPropertyToExpression(property); if (exp == null) return this as TSelect; - var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null); + var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery); if (isAscending) return this.OrderBy(field); return this.OrderBy($"{field} DESC"); } @@ -930,7 +1046,7 @@ namespace FreeSql.Internal.CommonProvider return new string[0]; } - var sql = _commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp, null, null, _params); + var sql = _commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp, _diymemexpWithTempQuery, null, _params); sb.Append(sql); } @@ -1042,6 +1158,19 @@ namespace FreeSql.Internal.CommonProvider return this as TSelect; } + public ISelect InternalWithTempQuery(Expression selector) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TDto)); //._dicSyced.TryAdd(typeof(TReturn), true); + var ret = (_orm as BaseDbProvider).CreateSelectProvider(null) as Select1Provider; + if (ret._tables[0].Table == null) ret._tables[0].Table = TableInfo.GetDefaultTable(typeof(TDto)); + var parser = new WithTempQueryParser(this, null, selector, ret._tables[0]); + var sql = $"\r\n{this.ToSql(parser._insideSelectList[0].InsideField)}"; + ret.WithSql(sql); + ret._diymemexpWithTempQuery = parser; + return ret; + } + public bool Any() { this.Limit(1); @@ -1079,6 +1208,7 @@ namespace FreeSql.Internal.CommonProvider public List ToList() => ToList(false); public virtual List ToList(bool includeNestedMembers) { + if (_diymemexpWithTempQuery != null) return this.ToListMapReaderPrivate((_diymemexpWithTempQuery as WithTempQueryParser)._insideSelectList[0].InsideAf, null); if (_selectExpression != null) return this.InternalToList(_selectExpression); return this.ToListPrivate(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null); } @@ -1123,6 +1253,7 @@ namespace FreeSql.Internal.CommonProvider public Task> ToListAsync(CancellationToken cancellationToken = default) => ToListAsync(false, cancellationToken); public virtual Task> ToListAsync(bool includeNestedMembers = false, CancellationToken cancellationToken = default) { + if (_diymemexpWithTempQuery != null) return this.ToListMapReaderPrivateAsync((_diymemexpWithTempQuery as WithTempQueryParser)._insideSelectList[0].InsideAf, null, cancellationToken); if (_selectExpression != null) return this.InternalToListAsync(_selectExpression, cancellationToken); return this.ToListPrivateAsync(includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null, cancellationToken); } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 66a7a791..20dddcd0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -28,7 +28,7 @@ namespace FreeSql.Internal.CommonProvider var property = properties[propIdx]; var exp = ConvertStringPropertyToExpression(property); if (exp == null) throw new Exception(CoreStrings.Property_Cannot_Find(property)); - var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null); + var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery); if (propIdx > 0) sbfield.Append(", "); sbfield.Append(field); //if (field != property) @@ -547,13 +547,21 @@ namespace FreeSql.Internal.CommonProvider static EventHandler _OldAuditDataReaderHandler; public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2(bool isRereadSql = true) { + if (_diymemexpWithTempQuery != null) + { + return new GetAllFieldExpressionTreeInfo + { + Field = "*", + Read = (orm, dr) => throw new Exception("GetAllFieldExpressionTreeInfo.Read Is Null") + }; + } if (_selectExpression != null) //ToSql { var af = this.GetExpressionField(_selectExpression); return new GetAllFieldExpressionTreeInfo { Field = af.field, - Read = (dr, idx) => throw new Exception("GetAllFieldExpressionTreeInfo.Read Is Null") + Read = (orm, dr) => throw new Exception("GetAllFieldExpressionTreeInfo.Read Is Null") }; } if (_OldAuditDataReaderHandler != _orm.Aop.AuditDataReaderHandler) @@ -751,7 +759,7 @@ namespace FreeSql.Internal.CommonProvider protected double InternalAvg(Expression exp) { - var field = $"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) { var list = this.ToList(field); @@ -764,7 +772,7 @@ namespace FreeSql.Internal.CommonProvider } protected TMember InternalMax(Expression exp) { - var field = $"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) return this.ToList(field).Max(); var sql = GetNestSelectSql(exp, field, ToSql); @@ -772,7 +780,7 @@ namespace FreeSql.Internal.CommonProvider } protected TMember InternalMin(Expression exp) { - var field = $"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) return this.ToList(field).Min(); var sql = GetNestSelectSql(exp, field, ToSql); @@ -780,7 +788,7 @@ namespace FreeSql.Internal.CommonProvider } protected decimal InternalSum(Expression exp) { - var field = $"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) return this.ToList(field).Sum(); var sql = GetNestSelectSql(exp, field, ToSql); @@ -793,14 +801,14 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, columns, null, null, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, columns, null, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany var sql = field.ToString(); this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null); return new SelectGroupingProvider(_orm, this, map, sql, _commonExpression, _tables); } public TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) { - _commonExpression.ExpressionJoinLambda(_tables, _tableRule, joinType, exp, null, _whereGlobalFilter); + _commonExpression.ExpressionJoinLambda(_tables, _tableRule, joinType, exp, _diymemexpWithTempQuery, _whereGlobalFilter); return this as TSelect; } protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) @@ -808,7 +816,7 @@ namespace FreeSql.Internal.CommonProvider var tb = _commonUtils.GetTableByEntity(typeof(T2)); if (tb == null) throw new ArgumentException(CoreStrings.T2_Type_Error); _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType }); - _commonExpression.ExpressionJoinLambda(_tables, _tableRule, joinType, exp, null, _whereGlobalFilter); + _commonExpression.ExpressionJoinLambda(_tables, _tableRule, joinType, exp, _diymemexpWithTempQuery, _whereGlobalFilter); return this as TSelect; } protected TSelect InternalOrderBy(Expression column) @@ -819,10 +827,10 @@ namespace FreeSql.Internal.CommonProvider case ExpressionType.New: var newExp = column as NewExpression; if (newExp == null) break; - for (var a = 0; a < newExp.Members.Count; a++) this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, newExp.Arguments[a], true, null)); + for (var a = 0; a < newExp.Members.Count; a++) this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, newExp.Arguments[a], true, _diymemexpWithTempQuery)); return this as TSelect; } - return this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, column, true, null)); + return this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, column, true, _diymemexpWithTempQuery)); } protected TSelect InternalOrderByDescending(Expression column) { @@ -832,10 +840,10 @@ namespace FreeSql.Internal.CommonProvider case ExpressionType.New: var newExp = column as NewExpression; if (newExp == null) break; - for (var a = 0; a < newExp.Members.Count; a++) this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, newExp.Arguments[a], true, null)} DESC"); + for (var a = 0; a < newExp.Members.Count; a++) this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, newExp.Arguments[a], true, _diymemexpWithTempQuery)} DESC"); return this as TSelect; } - return this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, column, true, null)} DESC"); + return this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, column, true, _diymemexpWithTempQuery)} DESC"); } public List InternalToList(Expression select) @@ -845,7 +853,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; var findSubSelectMany = new List(); - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, this, null, _whereGlobalFilter, null, findSubSelectMany, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, findSubSelectMany, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (findSubSelectMany.Any() == false) return this.ToListMapReaderPrivate(af, new ReadAnonymousTypeOtherInfo[0]); @@ -862,7 +870,7 @@ namespace FreeSql.Internal.CommonProvider { var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, find.Item1, this, null, _whereGlobalFilter, null, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, find.Item1, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, true); var otherRet = new List(); var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); afs.Add(NativeTuple.Create(find.Item1, find.Item2, otherAf)); @@ -947,7 +955,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = -10000; //临时规则,不返回 as1 - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, null, null, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, null, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany var childs = map.Childs; if (childs.Any() == false) throw new ArgumentException(CoreStrings.InsertInto_No_Property_Selected(typeof(TTargetEntity).DisplayCsharp())); @@ -1028,7 +1036,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, null, null, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, null, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (GetTableRuleUnions().Count <= 1) return this.ToListMapReader(af).FirstOrDefault(); @@ -1041,7 +1049,7 @@ namespace FreeSql.Internal.CommonProvider } } - public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp, null, _whereGlobalFilter, _params)); + public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); #region Async #if net40 @@ -1055,7 +1063,7 @@ namespace FreeSql.Internal.CommonProvider var property = properties[propIdx]; var exp = ConvertStringPropertyToExpression(property); if (exp == null) throw new Exception(CoreStrings.Property_Cannot_Find(property)); - var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null); + var field = _commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery); if (propIdx > 0) sbfield.Append(", "); sbfield.Append(field); //if (field != property) @@ -1299,7 +1307,7 @@ namespace FreeSql.Internal.CommonProvider async protected Task InternalAvgAsync(Expression exp, CancellationToken cancellationToken) { - var field = $"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) { var list = await this.ToListAsync(field, cancellationToken); @@ -1312,7 +1320,7 @@ namespace FreeSql.Internal.CommonProvider } async protected Task InternalMaxAsync(Expression exp, CancellationToken cancellationToken) { - var field = $"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) return (await this.ToListAsync(field, cancellationToken)).Max(); var sql = GetNestSelectSql(exp, field, ToSql); @@ -1320,7 +1328,7 @@ namespace FreeSql.Internal.CommonProvider } async protected Task InternalMinAsync(Expression exp, CancellationToken cancellationToken) { - var field = $"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) return (await this.ToListAsync(field, cancellationToken)).Min(); var sql = GetNestSelectSql(exp, field, ToSql); @@ -1328,7 +1336,7 @@ namespace FreeSql.Internal.CommonProvider } async protected Task InternalSumAsync(Expression exp, CancellationToken cancellationToken) { - var field = $"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}"; + var field = $"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, _tableRule, null, SelectTableInfoType.From, exp, true, _diymemexpWithTempQuery)}){_commonUtils.FieldAsAlias("as1")}"; if (_limit <= 0 && _skip <= 0) return (await this.ToListAsync(field, cancellationToken)).Sum(); var sql = GetNestSelectSql(exp, field, ToSql); @@ -1344,7 +1352,7 @@ namespace FreeSql.Internal.CommonProvider var index = 0; var findSubSelectMany = new List(); - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, this, null, _whereGlobalFilter, null, findSubSelectMany, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, findSubSelectMany, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (findSubSelectMany.Any() == false) return await this.ToListMapReaderPrivateAsync(af, new ReadAnonymousTypeOtherInfo[0], cancellationToken); @@ -1361,7 +1369,7 @@ namespace FreeSql.Internal.CommonProvider { var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, find.Item1, this, null, _whereGlobalFilter, null, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, find.Item1, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, true); var otherRet = new List(); var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); afs.Add(NativeTuple.Create(find.Item1, find.Item2, otherAf)); @@ -1521,7 +1529,7 @@ namespace FreeSql.Internal.CommonProvider var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, null, null, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select, null, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, false); //不走 DTO 映射,不处理 IncludeMany var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (GetTableRuleUnions().Count <= 1) return (await this.ToListMapReaderAsync(af, cancellationToken)).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs index 158548df..87a14edd 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider.cs @@ -27,16 +27,14 @@ namespace FreeSql.Internal.CommonProvider protected ISelect InternalFrom(LambdaExpression lambdaExp) { - if (lambdaExp != null) + if (lambdaExp == null) return this; + for (var a = 1; a < lambdaExp.Parameters.Count; a++) { - for (var a = 1; a < lambdaExp.Parameters.Count; a++) - { - var tb = _commonUtils.GetTableByEntity(lambdaExp.Parameters[a].Type); - if (tb == null) throw new ArgumentException(CoreStrings.Type_Error_Name(lambdaExp.Parameters[a].Name)); - _tables.Add(new SelectTableInfo { Table = tb, Alias = lambdaExp.Parameters[a].Name, On = null, Type = SelectTableInfoType.From }); - } + var tb = _commonUtils.GetTableByEntity(lambdaExp.Parameters[a].Type); + if (tb == null) throw new ArgumentException(CoreStrings.Type_Error_Name(lambdaExp.Parameters[a].Name)); + _tables.Add(new SelectTableInfo { Table = tb, Alias = lambdaExp.Parameters[a].Name, On = null, Type = SelectTableInfoType.From }); } - var exp = lambdaExp?.Body; + var exp = lambdaExp.Body; if (exp?.NodeType == ExpressionType.Call) { var expCall = exp as MethodCallExpression; @@ -60,7 +58,7 @@ namespace FreeSql.Internal.CommonProvider case "OrderBy": if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { - var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, _tableRule, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, _tableRule, null, SelectTableInfoType.From, expCall.Arguments[0], false, _diymemexpWithTempQuery); if (ifcond == "1" || ifcond == "'t'") this.InternalOrderBy(expCall.Arguments.LastOrDefault()); break; @@ -70,7 +68,7 @@ namespace FreeSql.Internal.CommonProvider case "OrderByDescending": if (expCall.Arguments.Count == 2 && expCall.Arguments[0].Type == typeof(bool)) { - var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, _tableRule, null, SelectTableInfoType.From, expCall.Arguments[0], false, null); + var ifcond = _commonExpression.ExpressionSelectColumn_MemberAccess(null, _tableRule, null, SelectTableInfoType.From, expCall.Arguments[0], false, _diymemexpWithTempQuery); if (ifcond == "1" || ifcond == "'t'" || ifcond == "-1")//MsAccess -1 this.InternalOrderByDescending(expCall.Arguments.LastOrDefault()); break; @@ -108,22 +106,47 @@ namespace FreeSql.Internal.CommonProvider return this.InternalAvg(column?.Body); } - public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp) where T2 : class; - public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp) where T2 : class where T3 : class; - public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class; + public abstract ISelect From(Expression, T2, ISelectFromExpression>> exp = null) where T2 : class; + public abstract ISelect From(Expression, T2, T3, ISelectFromExpression>> exp = null) where T2 : class where T3 : class; + public abstract ISelect From(Expression, T2, T3, T4, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class; - public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class; + public abstract ISelect From(Expression, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression>> exp = null) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class; + + + public ISelect FromQuery(ISelect select2) where T2 : class + { + var ret = From(); + var retsp = ret as Select0Provider; + var rettbs = retsp._tables; + if (rettbs[1].Table == null) rettbs[1].Table = TableInfo.GetDefaultTable(typeof(T2)); + (_diymemexpWithTempQuery as WithTempQueryParser)?.Append(select2, rettbs[1]); + var select2sp = select2 as Select0Provider; + string sql2 = null; + if (select2sp._diymemexpWithTempQuery == null) + sql2 = select2?.ToSql(a => a, FieldAliasOptions.AsProperty); + else + { + if (select2sp._tableRule != null && select2sp.IsDefaultSqlContent == true) + { + sql2 = select2sp._tableRule(select2sp._tables[0].Table.Type, null); + if (sql2.StartsWith("(") && sql2.EndsWith(")")) sql2 = sql2.Substring(1, sql2.Length - 2); + } + if (string.IsNullOrWhiteSpace(sql2)) + sql2 = select2?.ToSql("*"); + } + return ret.WithSql(null, sql2); + } public ISelectGrouping GroupBy(Expression> columns) { @@ -197,7 +220,7 @@ namespace FreeSql.Internal.CommonProvider var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select.Body, this, null, _whereGlobalFilter, findIncludeMany, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select.Body, this, _diymemexpWithTempQuery, _whereGlobalFilter, findIncludeMany, null, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (findIncludeMany.Any() == false) return this.ToListMapReaderPrivate(af, null); @@ -241,7 +264,7 @@ namespace FreeSql.Internal.CommonProvider var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, otherNewInit, this, null, _whereGlobalFilter, null, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, otherNewInit, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, true); var otherRet = new List(); var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); @@ -396,6 +419,8 @@ namespace FreeSql.Internal.CommonProvider return this; } + public ISelect WithTempQuery(Expression> selector) => InternalWithTempQuery(selector); + public bool Any(Expression> exp) { var oldwhere = _where.ToString(); @@ -440,7 +465,7 @@ namespace FreeSql.Internal.CommonProvider case TableRefType.OneToOne: _isIncluded = true; var curTb = _commonUtils.GetTableByEntity(exp.Type); - _commonExpression.ExpressionWhereLambda(_tables, _tableRule, Expression.MakeMemberAccess(exp, curTb.Properties[curTb.ColumnsByCs.First().Value.CsName]), null, null, null); + _commonExpression.ExpressionWhereLambda(_tables, _tableRule, Expression.MakeMemberAccess(exp, curTb.Properties[curTb.ColumnsByCs.First().Value.CsName]), _diymemexpWithTempQuery, null, null); break; } return this; @@ -459,7 +484,7 @@ namespace FreeSql.Internal.CommonProvider _isIncluded = true; _tables[0].Parameter = navigateSelector.Parameters[0]; - _commonExpression.ExpressionWhereLambda(_tables, _tableRule, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null); + _commonExpression.ExpressionWhereLambda(_tables, _tableRule, Expression.MakeMemberAccess(expBody, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), _diymemexpWithTempQuery, null, null); return this; } @@ -536,7 +561,7 @@ namespace FreeSql.Internal.CommonProvider if (tbNav == null) throw new Exception(CoreStrings.TypeError_CannotUse_IncludeMany(typeof(TNavigate).FullName)); if (collMem.Expression.NodeType != ExpressionType.Parameter) - _commonExpression.ExpressionWhereLambda(_tables, _tableRule, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), null, null, null); + _commonExpression.ExpressionWhereLambda(_tables, _tableRule, Expression.MakeMemberAccess(collMem.Expression, tb.Properties[tb.ColumnsByCs.First().Value.CsName]), _diymemexpWithTempQuery, null, null); TableRef tbref = null; var tbrefOneToManyColumns = new List>(); //临时 OneToMany 三个表关联,第三个表需要前两个表确定 @@ -1377,7 +1402,7 @@ namespace FreeSql.Internal.CommonProvider var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); var index = 0; - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select.Body, this, null, _whereGlobalFilter, findIncludeMany, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, map, ref index, select.Body, this, _diymemexpWithTempQuery, _whereGlobalFilter, findIncludeMany, null, true); var af = new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null); if (findIncludeMany.Any() == false) return await this.ToListMapReaderPrivateAsync(af, null, cancellationToken); @@ -1410,7 +1435,7 @@ namespace FreeSql.Internal.CommonProvider var otherMap = new ReadAnonymousTypeInfo(); field.Clear(); - _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, otherNewInit, this, null, _whereGlobalFilter, null, null, true); + _commonExpression.ReadAnonymousField(_tables, _tableRule, field, otherMap, ref index, otherNewInit, this, _diymemexpWithTempQuery, _whereGlobalFilter, null, null, true); var otherRet = new List(); var otherAf = new ReadAnonymousTypeOtherInfo(field.ToString(), otherMap, otherRet); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs index 74a14a82..b8eb5d4f 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select1Provider2`16.cs @@ -35,6 +35,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -171,14 +177,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -186,7 +192,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -201,6 +207,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -388,7 +400,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -489,6 +501,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -625,14 +643,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -640,7 +658,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -655,6 +673,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -842,7 +866,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -945,6 +969,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -1081,14 +1111,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -1096,7 +1126,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -1111,6 +1141,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -1298,7 +1334,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -1403,6 +1439,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -1539,14 +1581,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -1554,7 +1596,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -1569,6 +1611,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -1756,7 +1804,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -1863,6 +1911,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -1999,14 +2053,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -2014,7 +2068,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -2029,6 +2083,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -2216,7 +2276,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -2325,6 +2385,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -2461,14 +2527,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -2476,7 +2542,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -2491,6 +2557,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -2678,7 +2750,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -2789,6 +2861,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -2925,14 +3003,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -2940,7 +3018,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -2955,6 +3033,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -3142,7 +3226,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -3255,6 +3339,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -3391,14 +3481,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -3406,7 +3496,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -3421,6 +3511,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -3608,7 +3704,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -3723,6 +3819,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -3859,14 +3961,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -3874,7 +3976,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -3889,6 +3991,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -4076,7 +4184,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -4193,6 +4301,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -4329,14 +4443,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -4344,7 +4458,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -4359,6 +4473,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -4546,7 +4666,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -4665,6 +4785,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -4801,14 +4927,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -4816,7 +4942,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -4831,6 +4957,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -5018,7 +5150,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -5139,6 +5271,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -5275,14 +5413,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -5290,7 +5428,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -5305,6 +5443,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -5492,7 +5636,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -5615,6 +5759,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -5751,14 +5901,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -5766,7 +5916,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -5781,6 +5931,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -5968,7 +6124,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -6093,6 +6249,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -6229,14 +6391,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -6244,7 +6406,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -6259,6 +6421,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -6446,7 +6614,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } @@ -6573,6 +6741,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect.WithTempQuery(Expression> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect.Avg(Expression> column) { if (column == null) return default(double); @@ -6709,14 +6883,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect ISelect.WhereIf(bool condition, Expression> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect.Any(Expression> exp) @@ -6724,7 +6898,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -6739,6 +6913,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect.WithTempQuery(Expression, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect).WithTempQuery((Expression>)expModify); + } + double ISelect.Avg(Expression, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -6926,7 +7106,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index e8a45ab5..0cb9b7c0 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -32,7 +32,12 @@ namespace FreeSql.Internal.CommonProvider public override string ParseExp(Expression[] members) { - if (members.Any() == false) return _map.DbField; + ParseExpMapResult = null; + if (members.Any() == false) + { + ParseExpMapResult = _map; + return _map.DbField; + } var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; switch (parentName) { @@ -43,6 +48,7 @@ namespace FreeSql.Internal.CommonProvider read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault(); if (read == null) return null; } + ParseExpMapResult = read; return read.DbField; case "Value": var tb = _tables.First(); @@ -192,6 +198,19 @@ namespace FreeSql.Internal.CommonProvider } public string ToSql(string field) => InternalToSql(field); + public ISelect WithTempQuery(Expression, TDto>> selector) + { + if (_orm.CodeFirst.IsAutoSyncStructure) + (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TDto)); //._dicSyced.TryAdd(typeof(TReturn), true); + var ret = (_orm as BaseDbProvider).CreateSelectProvider(null) as Select1Provider; + if (ret._tables[0].Table == null) ret._tables[0].Table = TableInfo.GetDefaultTable(typeof(TDto)); + var parser = new Select0Provider.WithTempQueryParser(_select, this, selector, ret._tables[0]); + var sql = this.ToSql(parser._insideSelectList[0].InsideField); + ret.WithSql(sql); + ret._diymemexpWithTempQuery = parser; + return ret; + } + public ISelectGrouping Skip(int offset) { _groupBySkip = offset; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt index d166885a..73017de9 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/ISelect2`16.tt @@ -120,6 +120,8 @@ public interface ISelect<<#=NewStr #>> : ISelect0>, T1> <#= ISelect<<#=NewStr #>> WithSql(<#=string.Join(",",WithSql)#>, object parms = null); + ISelect WithTempQuery(Expression, TDto>> selector); + #region HzyTuple 元组 bool Any(Expression>, bool>> exp); @@ -150,6 +152,8 @@ public interface ISelect<<#=NewStr #>> : ISelect0>, T1> <#= ISelect<<#=NewStr #>> OrderByDescending(Expression>, TMember>> column); ISelect<<#=NewStr #>> OrderByIf(bool condition, Expression>, TMember>> column, bool descending = false); + ISelect WithTempQuery(Expression>, TDto>> selector); + #endregion } diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt index 70b39351..4ea97916 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt +++ b/FreeSql/Internal/CommonProvider/SelectProvider/T4Temp/Select1Provider2`16.tt @@ -83,6 +83,12 @@ namespace FreeSql.Internal.CommonProvider return this; } + ISelect ISelect<<#=NewStr #>>.WithTempQuery(Expression, TDto>> selector) + { + for (var a = 0; a < selector.Parameters.Count; a++) _tables[a].Parameter = selector.Parameters[a]; + return this.InternalWithTempQuery(selector); + } + double ISelect<<#=NewStr #>>.Avg(Expression, TMember>> column) { if (column == null) return default(double); @@ -219,14 +225,14 @@ namespace FreeSql.Internal.CommonProvider { if (exp == null) return this.Where(null); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } ISelect<<#=NewStr #>> ISelect<<#=NewStr #>>.WhereIf(bool condition, Expression, bool>> exp) { if (condition == false || exp == null) return this; for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; - return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)); + return this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)); } bool ISelect<<#=NewStr #>>.Any(Expression, bool>> exp) @@ -234,7 +240,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return this.Any(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).Any(); + var ret = this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).Any(); _where.Clear().Append(oldwhere); return ret; } @@ -249,6 +255,12 @@ namespace FreeSql.Internal.CommonProvider #region HzyTuple 元组 + ISelect ISelect<<#=NewStr #>>.WithTempQuery(Expression>, TDto>> selector) + { + var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(selector, _tables); + return (this as ISelect<<#=NewStr #>>).WithTempQuery((Expression, TDto>>)expModify); + } + double ISelect<<#=NewStr #>>.Avg(Expression>, TMember>> column) { var expModify = new CommonExpression.ReplaceHzyTupleToMultiParam().Modify(column, _tables); @@ -436,7 +448,7 @@ namespace FreeSql.Internal.CommonProvider if (exp == null) return await this.AnyAsync(); for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a]; var oldwhere = _where.ToString(); - var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, null, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); + var ret = await this.Where(_commonExpression.ExpressionWhereLambda(_tables, _tableRule, exp?.Body, _diymemexpWithTempQuery, _whereGlobalFilter, _params)).AnyAsync(cancellationToken); _where.Clear().Append(oldwhere); return ret; } diff --git a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs index d118b0aa..27c50960 100644 --- a/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs +++ b/FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; @@ -15,6 +16,7 @@ namespace FreeSql.Internal.Model public Type CsType { get; set; } public Type MapType { get; set; } public string DbField { get; set; } + public string DbNestedField { get; set; } public ConstructorInfo Consturctor { get; set; } public List Childs = new List(); public TableInfo Table { get; set; } @@ -31,12 +33,37 @@ namespace FreeSql.Internal.Model target.CsType = CsType; target.MapType = MapType; target.DbField = DbField; + target.DbNestedField = DbNestedField; target.Consturctor = Consturctor; - target.Childs = Childs; + LocalEachCopyChilds(Childs, target.Childs); target.Table = Table; target.IsEntity = IsEntity; target.IsDefaultCtor = IsDefaultCtor; target.IncludeManyKey = IncludeManyKey; + + void LocalEachCopyChilds(List from, List to) + { + foreach(var fromChild in from) + { + var toChild = new ReadAnonymousTypeInfo(); + fromChild.CopyTo(toChild); + to.Add(toChild); + } + } + } + + public List GetAllChilds(int maxDepth = 10) + { + if (maxDepth <= 0) return new List(); + var allchilds = new List(); + foreach (var child in Childs) + { + if (child.Childs.Any()) + allchilds.AddRange(child.GetAllChilds(maxDepth - 1)); + else + allchilds.Add(child); + } + return allchilds; } } public class ReadAnonymousTypeAfInfo diff --git a/FreeSql/Internal/Model/TableInfo.cs b/FreeSql/Internal/Model/TableInfo.cs index 13555dfd..5ba67184 100644 --- a/FreeSql/Internal/Model/TableInfo.cs +++ b/FreeSql/Internal/Model/TableInfo.cs @@ -50,6 +50,18 @@ namespace FreeSql.Internal.Model } public IEnumerable> GetAllTableRef() => _refs; + public static TableInfo GetDefaultTable(Type type) => new TableInfo + { + CsName = type.Name, + DbName = type.Name, + DisableSyncStructure = true, + Primarys = new ColumnInfo[0], + ColumnsByPosition = new ColumnInfo[0], + ColumnsByCanUpdateDbUpdateValue = new ColumnInfo[0], + Properties = type.GetPropertiesDictIgnoreCase(), + Type = type, + }; + //public void CopyTo(TableInfo target) //{ // target.Type = this.Type;