- 增加 ISelect<T> FromQuery 重载多表嵌套;

This commit is contained in:
2881099 2023-03-03 00:37:18 +08:00
parent 5c5116c650
commit 8b5b23202c
6 changed files with 348 additions and 197 deletions

View File

@ -800,14 +800,5 @@
<param name="that"></param> <param name="that"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
<summary>
批量注入 Repository可以参考代码自行调整
</summary>
<param name="services"></param>
<param name="globalDataFilter"></param>
<param name="assemblies"></param>
<returns></returns>
</member>
</members> </members>
</doc> </doc>

View File

@ -51,6 +51,39 @@ FROM (
INNER JOIN [Instruction] c ON b.[InstructionNo] = c.[InstructionNo] ) b ON a.[SeqNoLog] = b.[SeqNoLog] ) a INNER JOIN [Instruction] c ON b.[InstructionNo] = c.[InstructionNo] ) b ON a.[SeqNoLog] = b.[SeqNoLog] ) a
INNER JOIN [Unit] b ON a.[UnitId] = b.[UnitId] INNER JOIN [Unit] b ON a.[UnitId] = b.[UnitId]
WHERE (a.[RN] < 2)", sql); WHERE (a.[RN] < 2)", sql);
sql = fsql.Select<UnitLog>().FromQuery(
fsql.Select<UnitLog, LoadPlan, Instruction>()
.InnerJoin((a, b, c) => a.LoadNo == b.LoadNo && a.UnitTransactionType == "TO")
.InnerJoin((a, b, c) => b.InstructionNo == c.InstructionNo)
.WithTempQuery((a, b, c) => new
{
a.LoadNo,
a.SeqNoLog,
c.DeliveryInstractionStatus,
c.UpTime,
RN = SqlExt.RowNumber().Over().PartitionBy(a.UnitId).OrderByDescending(a.SeqNoLog).ToValue()
}),
fsql.Select<Unit>())
.InnerJoin((a,b,c) => a.SeqNoLog == b.SeqNoLog)
.InnerJoin((a,b,c) => a.UnitId == c.UnitId)
.Where((a,b,c) => b.RN < 2)
.ToSql((a,b,c) => new MB51_View
{
//CkassIfCation = a.Item1.CkassIfCation,
PGI = b.DeliveryInstractionStatus,
PGITime = b.UpTime,
IsDelayPGI = true,
RunNo = c.RunNo
});
Assert.Equal(@"SELECT a.[CkassIfCation] as1, b.[DeliveryInstractionStatus] as2, b.[UpTime] as3, 1 as4, c.[RunNo] as5
FROM [UnitLog] a
INNER JOIN (SELECT a.[LoadNo], a.[SeqNoLog], c.[DeliveryInstractionStatus], c.[UpTime], row_number() over( partition by a.[UnitId] order by a.[SeqNoLog] desc) [RN]
FROM [UnitLog] a
INNER JOIN [LoadPlan] b ON a.[LoadNo] = b.[LoadNo] AND a.[UnitTransactionType] = N'TO'
INNER JOIN [Instruction] c ON b.[InstructionNo] = c.[InstructionNo] ) b ON a.[SeqNoLog] = b.[SeqNoLog]
INNER JOIN [Unit] c ON a.[UnitId] = c.[UnitId]
WHERE (b.[RN] < 2)", sql);
} }
class MB51_View class MB51_View
{ {

View File

@ -3349,177 +3349,6 @@
<param name="parms"></param> <param name="parms"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.IAdo.ExecuteConnectTestAsync(System.Int32,System.Threading.CancellationToken)">
<summary>
测试数据库是否连接正确,本方法执行如下命令:<para></para>
MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1<para></para>
Oracle: SELECT 1 FROM dual<para></para>
</summary>
<param name="commandTimeout">命令超时设置(秒)</param>
<param name="cancellationToken"></param>
<returns>true: 成功, false: 失败</returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询若使用读写分离查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
</summary>
<param name="readerHander"></param>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="readerHander"></param>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
在【主库】执行ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
在【主库】执行ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<typeparam name="T"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T1"></typeparam>
<typeparam name="T2"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合Query&lt;User, Address&gt;("select * from user where age > @age; select * from address", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<typeparam name="T1"></typeparam>
<typeparam name="T2"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="E:FreeSql.IAop.ParseExpression"> <member name="E:FreeSql.IAop.ParseExpression">
<summary> <summary>
可自定义解析表达式 可自定义解析表达式
@ -4510,12 +4339,6 @@
<param name="timeout">超时</param> <param name="timeout">超时</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.GetAsync">
<summary>
获取资源
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)"> <member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)">
<summary> <summary>
使用完毕后,归还资源 使用完毕后,归还资源
@ -4591,12 +4414,6 @@
</summary> </summary>
<param name="obj">资源对象</param> <param name="obj">资源对象</param>
</member> </member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnGetAsync(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
从对象池获取对象成功的时候触发,通过该方法统计或初始化对象
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})"> <member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})">
<summary> <summary>
归还对象给对象池的时候触发 归还对象给对象池的时候触发
@ -6038,3 +5855,222 @@
</member> </member>
</members> </members>
</doc> </doc>
ystem.Boolean}})">
<summary>
使用 and 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``4(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``4(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``4(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}},System.Boolean)">
<summary>
将 lambda 表达式取反
</summary>
<param name="exp"></param>
<param name="condition">true 时生效</param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 and 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 and 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean)">
<summary>
将 lambda 表达式取反
</summary>
<param name="exp"></param>
<param name="condition">true 时生效</param>
<returns></returns>
</member>
<member name="M:FreeUtil.NewMongodbId">
<summary>
生成类似Mongodb的ObjectId有序、不重复Guid
</summary>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1">
<summary>
插入数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0)">
<summary>
插入数据,传入实体
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0[])">
<summary>
插入数据,传入实体数组
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.List{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.IEnumerable{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.InsertOrUpdate``1">
<summary>
插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下:<para></para>
MySql 5.6+: on duplicate key update<para></para>
PostgreSQL 9.4+: on conflict do update<para></para>
SqlServer 2008+: merge into<para></para>
Oracle 11+: merge into<para></para>
Sqlite: replace into<para></para>
达梦: merge into<para></para>
人大金仓on conflict do update<para></para>
神通merge into<para></para>
MsAccess不支持<para></para>
注意区别FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性)
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1">
<summary>
修改数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1(System.Object)">
<summary>
修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1">
<summary>
查询数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1(System.Object)">
<summary>
查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1">
<summary>
删除数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1(System.Object)">
<summary>
删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Transaction(System.Action)">
<summary>
开启事务(不支持异步)<para></para>
v1.5.0 关闭了线程事务超时自动提交的机制
</summary>
<param name="handler">事务体 () => {}</param>
</member>
<member name="M:IFreeSql.Transaction(System.Data.IsolationLevel,System.Action)">
<summary>
开启事务(不支持异步)<para></para>
v1.5.0 关闭了线程事务超时自动提交的机制
</summary>
<param name="isolationLevel"></param>
<param name="handler">事务体 () => {}</param>
</member>
<member name="P:IFreeSql.Ado">
<summary>
数据库访问对象
</summary>
</member>
<member name="P:IFreeSql.Aop">
<summary>
所有拦截方法都在这里
</summary>
</member>
<member name="P:IFreeSql.CodeFirst">
<summary>
CodeFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.DbFirst">
<summary>
DbFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.GlobalFilter">
<summary>
全局过滤设置,可默认附加为 Select/Update/Delete 条件
</summary>
</member>
</members>
</doc>

View File

@ -193,6 +193,9 @@ namespace FreeSql
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> 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<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> 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<T1, T2> FromQuery<T2>(ISelect<T2> select2) where T2 : class; ISelect<T1, T2> FromQuery<T2>(ISelect<T2> select2) where T2 : class;
ISelect<T1, T2, T3> FromQuery<T2, T3>(ISelect<T2> select2, ISelect<T3> select3) where T2 : class where T3 : class;
ISelect<T1, T2, T3, T4> FromQuery<T2, T3, T4>(ISelect<T2> select2, ISelect<T3> select3, ISelect<T4> select4) where T2 : class where T3 : class where T4 : class;
ISelect<T1, T2, T3, T4, T5> FromQuery<T2, T3, T4, T5>(ISelect<T2> select2, ISelect<T3> select3, ISelect<T4> select4, ISelect<T5> select5) where T2 : class where T3 : class where T4 : class where T5 : class;
ISelect<T1> UnionAll(params ISelect<T1>[] querys); ISelect<T1> UnionAll(params ISelect<T1>[] querys);
/// <summary> /// <summary>

View File

@ -80,6 +80,9 @@ namespace FreeSql.Internal.CommonProvider
_diymemexpWithTempQuery = null; _diymemexpWithTempQuery = null;
} }
public abstract string ToSqlBase(string field = null);
public abstract void AsTableBase(Func<Type, string, string> tableRule);
public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection<ParameterExpression> lambParms) public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection<ParameterExpression> lambParms)
{ {
if (to == null) return; if (to == null) return;
@ -221,9 +224,10 @@ namespace FreeSql.Internal.CommonProvider
} }
} }
public WithTempQueryParser Append<TDto>(ISelect<TDto> select, SelectTableInfo outsideTable) public WithTempQueryParser Append(Select0Provider select, SelectTableInfo outsideTable)
{ {
if (outsideTable != null && (select as Select0Provider)?._diymemexpWithTempQuery is WithTempQueryParser withTempQuery) //select is ISelect<T>
if (outsideTable != null && select?._diymemexpWithTempQuery is WithTempQueryParser withTempQuery)
{ {
_insideSelectList.Add(withTempQuery._insideSelectList[0]); _insideSelectList.Add(withTempQuery._insideSelectList[0]);
_outsideTable.Add(outsideTable); _outsideTable.Add(outsideTable);
@ -927,6 +931,7 @@ namespace FreeSql.Internal.CommonProvider
} }
return unions; return unions;
} }
public override void AsTableBase(Func<Type, string, string> tableRule) => AsTable(tableRule);
public TSelect AsTable(Func<Type, string, string> tableRule) public TSelect AsTable(Func<Type, string, string> tableRule)
{ {
if (_tableRules.Count == 1 && _diymemexpWithTempQuery != null && _diymemexpWithTempQuery is WithTempQueryParser tempQueryParser) if (_tableRules.Count == 1 && _diymemexpWithTempQuery != null && _diymemexpWithTempQuery is WithTempQueryParser tempQueryParser)
@ -958,6 +963,7 @@ namespace FreeSql.Internal.CommonProvider
if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType);
return this as TSelect; return this as TSelect;
} }
public override string ToSqlBase(string field = null) => ToSql(field);
public abstract string ToSql(string field = null); public abstract string ToSql(string field = null);
public TSelect Where(string sql, object parms = null) => this.WhereIf(true, sql, parms); public TSelect Where(string sql, object parms = null) => this.WhereIf(true, sql, parms);

View File

@ -123,15 +123,14 @@ namespace FreeSql.Internal.CommonProvider
public abstract ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression<T1>>> 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<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, ISelectFromExpression<T1>>> 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<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> 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 abstract ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> 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<T1, T2> FromQuery<T2>(ISelect<T2> select2) where T2 : class public ISelect<T1, T2> FromQuery<T2>(ISelect<T2> select2) where T2 : class
{ {
var ret = From<T2>(); var ret = From<T2>();
var retsp = ret as Select0Provider; var retsp = ret as Select0Provider;
var rettbs = retsp._tables; var rettbs = retsp._tables;
if (rettbs[1].Table == null) rettbs[1].Table = TableInfo.GetDefaultTable(typeof(T2)); if (rettbs[1].Table == null) rettbs[1].Table = TableInfo.GetDefaultTable(typeof(T2));
(_diymemexpWithTempQuery as WithTempQueryParser)?.Append(select2, rettbs[1]);
var select2sp = select2 as Select0Provider; var select2sp = select2 as Select0Provider;
(_diymemexpWithTempQuery as WithTempQueryParser)?.Append(select2sp, rettbs[1]);
string sql2 = null; string sql2 = null;
if (select2sp._diymemexpWithTempQuery == null) if (select2sp._diymemexpWithTempQuery == null)
{ {
@ -142,7 +141,7 @@ namespace FreeSql.Internal.CommonProvider
else else
{ {
if (retsp._diymemexpWithTempQuery == null) if (retsp._diymemexpWithTempQuery == null)
retsp._diymemexpWithTempQuery = new WithTempQueryParser(null, null, null, null).Append(select2, rettbs[1]); retsp._diymemexpWithTempQuery = new WithTempQueryParser(null, null, null, null).Append(select2sp, rettbs[1]);
if (select2sp._tableRule != null && select2sp.IsDefaultSqlContent == true) if (select2sp._tableRule != null && select2sp.IsDefaultSqlContent == true)
{ {
sql2 = select2sp._tableRule(select2sp._tables[0].Table.Type, null); sql2 = select2sp._tableRule(select2sp._tables[0].Table.Type, null);
@ -172,6 +171,89 @@ namespace FreeSql.Internal.CommonProvider
if (retsp._tableRules.Count == 0) ret.WithSql(null, $" \r\n{sql2}"); if (retsp._tableRules.Count == 0) ret.WithSql(null, $" \r\n{sql2}");
return ret; return ret;
} }
public TQuery FromQueryMulti<TQuery>(TQuery ret, Type[] entityTypes, Select0Provider[] querys)
{
var retsp = ret as Select0Provider;
var rettbs = retsp._tables;
var sql2List = new string[rettbs.Count - 1];
for (var a = 1; a < rettbs.Count; a++)
{
var select2 = querys[a - 1];
var entityType2 = entityTypes[a - 1];
var rettb2 = rettbs[a];
if (rettb2.Table == null) rettb2.Table = TableInfo.GetDefaultTable(entityType2);
(_diymemexpWithTempQuery as WithTempQueryParser)?.Append(select2, rettb2);
string sql2 = null;
if (select2._diymemexpWithTempQuery == null)
{
if (select2._tableRule == null && select2._tables[0].Table.Type == entityType2 && select2.IsDefaultSqlContent == true)
continue;
var selectorParameter = Expression.Parameter(entityType2);
var selector = Expression.Lambda(selectorParameter, selectorParameter);
select2._tables[0].Parameter = selectorParameter;
var af = this.GetExpressionField(selector, FieldAliasOptions.AsProperty);
sql2 = this.ToSql(af.field);
}
else
{
if (retsp._diymemexpWithTempQuery == null)
retsp._diymemexpWithTempQuery = new WithTempQueryParser(null, null, null, null).Append(select2, rettb2);
if (select2._tableRule != null && select2.IsDefaultSqlContent == true)
{
sql2 = select2._tableRule(select2._tables[0].Table.Type, null);
if (sql2.StartsWith("(") && sql2.EndsWith(")")) sql2 = sql2.Substring(1, sql2.Length - 2);
if (sql2.StartsWith(" \r\n")) sql2 = sql2.Substring(3);
}
if (string.IsNullOrWhiteSpace(sql2))
sql2 = select2.ToSqlBase("*");
}
sql2List[a - 1] = sql2;
}
if (retsp._tableRules.Count > 0)
{
var tbrules = retsp._tableRules.ToList();
retsp._tableRules.Clear();
tbrules.ForEach(tbrule =>
{
var tbruler1 = tbrule(typeof(T1), retsp._tables[0].Table.DbName);
if (string.IsNullOrWhiteSpace(tbruler1) == false)
retsp._tableRules.Add((type, old) =>
{
if (type == typeof(T1)) return tbruler1;
for (var a = 0; a < entityTypes.Length; a++)
if (entityTypes[a] == type) return string.IsNullOrWhiteSpace(sql2List[a]) ? old : $"( \r\n{sql2List[a]})";
return old;
});
});
}
if (retsp._tableRules.Count == 0)
{
retsp.AsTableBase((type, old) =>
{
for (var a = 0; a < entityTypes.Length; a++)
if (entityTypes[a] == type) return string.IsNullOrWhiteSpace(sql2List[a]) ? old : $"({sql2List[a]})";
return old;
});
}
return ret;
}
public ISelect<T1, T2, T3> FromQuery<T2, T3>(ISelect<T2> select2, ISelect<T3> select3) where T2 : class where T3 : class
{
var ret = From<T2, T3>();
return FromQueryMulti(ret, new[] { typeof(T2), typeof(T3) }, new[] { select2 as Select0Provider, select3 as Select0Provider });
}
public ISelect<T1, T2, T3, T4> FromQuery<T2, T3, T4>(ISelect<T2> select2, ISelect<T3> select3, ISelect<T4> select4) where T2 : class where T3 : class where T4 : class
{
var ret = From<T2, T3, T4>();
return FromQueryMulti(ret, new[] { typeof(T2), typeof(T3), typeof(T4) }, new[] { select2 as Select0Provider, select3 as Select0Provider, select4 as Select0Provider });
}
public ISelect<T1, T2, T3, T4, T5> FromQuery<T2, T3, T4, T5>(ISelect<T2> select2, ISelect<T3> select3, ISelect<T4> select4, ISelect<T5> select5) where T2 : class where T3 : class where T4 : class where T5 : class
{
var ret = From<T2, T3, T4, T5>();
return FromQueryMulti(ret, new[] { typeof(T2), typeof(T3), typeof(T4), typeof(T5) }, new[] { select2 as Select0Provider, select3 as Select0Provider, select4 as Select0Provider, select5 as Select0Provider });
}
public ISelect<T1> UnionAll(params ISelect<T1>[] querys) public ISelect<T1> UnionAll(params ISelect<T1>[] querys)
{ {
var sql1 = this.ToSql(); var sql1 = this.ToSql();