mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	Reflection 替换 ExpressionTree,单元测试已通过
This commit is contained in:
		@@ -56,6 +56,11 @@ namespace FreeSql.Tests.PerformanceTest {
 | 
				
			|||||||
			time.Stop();
 | 
								time.Stop();
 | 
				
			||||||
			sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*");
 | 
								sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								time.Restart();
 | 
				
			||||||
 | 
								var t41 = g.mysql.Select<xxx>().ToList<(int, string, string)>("id,title,url");
 | 
				
			||||||
 | 
								time.Stop();
 | 
				
			||||||
 | 
								sb.AppendLine($"Elapsed: {time.Elapsed}; Query ToList<Tuple> Counts: {t41.Count}; ORM: FreeSql*");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			time.Restart();
 | 
								time.Restart();
 | 
				
			||||||
			var t5 = g.mysql.Ado.Query<dynamic>("select * from song");
 | 
								var t5 = g.mysql.Ado.Query<dynamic>("select * from song");
 | 
				
			||||||
			time.Stop();
 | 
								time.Stop();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -278,8 +278,8 @@ namespace FreeSql.Tests.PostgreSQL {
 | 
				
			|||||||
				testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 },
 | 
									testFielLongArrayNullable = new long?[] { 500, 600, 700, null, 999, 1000 },
 | 
				
			||||||
				testFielLongNullable = long.MinValue
 | 
									testFielLongNullable = long.MinValue
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			var item3 = insert.AppendData(item2).ExecuteInserted();
 | 
								var item3 = insert.AppendData(item2).ExecuteInserted().First();
 | 
				
			||||||
			var newitem2 = select.Where(a => a.Id == item2.Id).ToOne();
 | 
								var newitem2 = select.Where(a => a.Id == item3.Id).ToOne();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var items = select.ToList();
 | 
								var items = select.ToList();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ namespace FreeSql.Tests {
 | 
				
			|||||||
				
 | 
									
 | 
				
			||||||
				.Any()
 | 
									.Any()
 | 
				
			||||||
				).Any()
 | 
									).Any()
 | 
				
			||||||
			).ToSql();
 | 
								).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var groupby = g.mysql.Select<TestInfo>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
 | 
								var groupby = g.mysql.Select<TestInfo>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
 | 
				
			||||||
@@ -38,7 +38,7 @@ namespace FreeSql.Tests {
 | 
				
			|||||||
			.Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100)
 | 
								.Having(a => a.Count() < 300 || a.Avg(a.Key.mod4) < 100)
 | 
				
			||||||
			.OrderBy(a => a.Key.tt2)
 | 
								.OrderBy(a => a.Key.tt2)
 | 
				
			||||||
			.OrderByDescending(a => a.Count())
 | 
								.OrderByDescending(a => a.Count())
 | 
				
			||||||
			.ToSql(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4),
 | 
								.ToList(a => new { a.Key.tt2, cou1 = a.Count(), arg1 = a.Avg(a.Key.mod4),
 | 
				
			||||||
				ccc2 = a.Key.tt2 ?? "now()",
 | 
									ccc2 = a.Key.tt2 ?? "now()",
 | 
				
			||||||
				//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
 | 
									//ccc = Convert.ToDateTime("now()"), partby = Convert.ToDecimal("sum(num) over(PARTITION BY server_id,os,rid,chn order by id desc)")
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
@@ -47,13 +47,13 @@ namespace FreeSql.Tests {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			var arrg222 = g.mysql.Select<NullAggreTestTable>().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) });
 | 
								var arrg222 = g.mysql.Select<NullAggreTestTable>().ToAggregate(a => new { sum = a.Sum(a.Key.Id + 11.11), avg = a.Avg(a.Key.Id), count = a.Count(), max = a.Max(a.Key.Id), min = a.Min(a.Key.Id) });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var t1 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
 | 
								var t1 = g.mysql.Select<TestInfo>().Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
 | 
				
			||||||
			var t2 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToSql();
 | 
								var t2 = g.mysql.Select<TestInfo>().As("b").Where("").Where(a => a.Id > 0).Skip(100).Limit(200).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToSql();
 | 
								var sql1 = select.LeftJoin(a => a.Type.Guid == a.TypeGuid).ToList();
 | 
				
			||||||
			var sql2 = select.LeftJoin<TestTypeInfo>((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToSql();
 | 
								var sql2 = select.LeftJoin<TestTypeInfo>((a, b) => a.TypeGuid == b.Guid && b.Name == "111").ToList();
 | 
				
			||||||
			var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToSql();
 | 
								var sql3 = select.LeftJoin("TestTypeInfo b on b.Guid = a.TypeGuid").ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			//g.mysql.Select<TestInfo, TestTypeInfo, TestTypeParentInfo>().Join((a, b, c) => new Model.JoinResult3(
 | 
								//g.mysql.Select<TestInfo, TestTypeInfo, TestTypeParentInfo>().Join((a, b, c) => new Model.JoinResult3(
 | 
				
			||||||
			//   Model.JoinType.LeftJoin, a.TypeGuid == b.Guid,
 | 
								//   Model.JoinType.LeftJoin, a.TypeGuid == b.Guid,
 | 
				
			||||||
@@ -69,7 +69,7 @@ namespace FreeSql.Tests {
 | 
				
			|||||||
			var sql4 = select.From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
 | 
								var sql4 = select.From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s
 | 
				
			||||||
				.InnerJoin(a => a.TypeGuid == b.Guid)
 | 
									.InnerJoin(a => a.TypeGuid == b.Guid)
 | 
				
			||||||
				.LeftJoin(a => c.Id == b.ParentId)
 | 
									.LeftJoin(a => c.Id == b.ParentId)
 | 
				
			||||||
				.Where(a => b.Name == "xxx")).ToSql();
 | 
									.Where(a => b.Name == "xxx")).ToList();
 | 
				
			||||||
			//.Where(a => a.Id == 1).ToSql();
 | 
								//.Where(a => a.Id == 1).ToSql();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
@@ -94,12 +94,12 @@ namespace FreeSql.Tests {
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var ttt122 = g.mysql.Select<TestTypeParentInfo>().Where(a => a.Id > 0).ToSql();
 | 
								var ttt122 = g.mysql.Select<TestTypeParentInfo>().Where(a => a.Id > 0).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var sql5 = g.mysql.Select<TestInfo>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToSql();
 | 
								var sql5 = g.mysql.Select<TestInfo>().From<TestTypeInfo, TestTypeParentInfo>((s, b, c) => s).Where((a, b, c) => a.Id == b.ParentId).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  <PropertyGroup>
 | 
					  <PropertyGroup>
 | 
				
			||||||
    <TargetFramework>netstandard2.0</TargetFramework>
 | 
					    <TargetFramework>netstandard2.0</TargetFramework>
 | 
				
			||||||
    <Version>0.0.7</Version>
 | 
					    <Version>0.0.8</Version>
 | 
				
			||||||
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
					    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
				
			||||||
    <Authors>YeXiangQin</Authors>
 | 
					    <Authors>YeXiangQin</Authors>
 | 
				
			||||||
    <Description>打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite 数据库。</Description>
 | 
					    <Description>打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite 数据库。</Description>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,7 +50,7 @@ namespace FreeSql {
 | 
				
			|||||||
		#endregion
 | 
							#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
							/// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="readerHander"></param>
 | 
							/// <param name="readerHander"></param>
 | 
				
			||||||
		/// <param name="cmdType"></param>
 | 
							/// <param name="cmdType"></param>
 | 
				
			||||||
@@ -58,18 +58,38 @@ namespace FreeSql {
 | 
				
			|||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
							/// 查询,ExecuteReader(dr => {}, "select * from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							void ExecuteReader(Action<DbDataReader> readerHander, string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 查询
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdText"></param>
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
							/// 查询,ExecuteArray("select * from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							object[][] ExecuteArray(string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 查询
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdText"></param>
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 查询,ExecuteDataTable("select * from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							DataTable ExecuteDataTable(string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 在【主库】执行
 | 
							/// 在【主库】执行
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdType"></param>
 | 
							/// <param name="cmdType"></param>
 | 
				
			||||||
@@ -77,12 +97,26 @@ namespace FreeSql {
 | 
				
			|||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 在【主库】执行,ExecuteNonQuery("delete from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							int ExecuteNonQuery(string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 在【主库】执行
 | 
							/// 在【主库】执行
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdType"></param>
 | 
							/// <param name="cmdType"></param>
 | 
				
			||||||
		/// <param name="cmdText"></param>
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 在【主库】执行,ExecuteScalar("select 1 from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							object ExecuteScalar(string cmdText, object parms = null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
							/// 执行SQL返回对象集合,Query<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
				
			||||||
@@ -104,7 +138,7 @@ namespace FreeSql {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		#region async
 | 
							#region async
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
							/// 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="readerHander"></param>
 | 
							/// <param name="readerHander"></param>
 | 
				
			||||||
		/// <param name="cmdType"></param>
 | 
							/// <param name="cmdType"></param>
 | 
				
			||||||
@@ -112,18 +146,38 @@ namespace FreeSql {
 | 
				
			|||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
							/// 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 查询
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdText"></param>
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		Task<object[][]> ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							Task<object[][]> ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
 | 
							/// 查询,ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							Task<object[][]> ExecuteArrayAsync(string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 查询
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdText"></param>
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		Task<DataTable> ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							Task<DataTable> ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 查询,ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							Task<DataTable> ExecuteDataTableAsync(string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 在【主库】执行
 | 
							/// 在【主库】执行
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdType"></param>
 | 
							/// <param name="cmdType"></param>
 | 
				
			||||||
@@ -131,12 +185,26 @@ namespace FreeSql {
 | 
				
			|||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							Task<int> ExecuteNonQueryAsync(string cmdText, object parms = null);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
		/// 在【主库】执行
 | 
							/// 在【主库】执行
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <param name="cmdType"></param>
 | 
							/// <param name="cmdType"></param>
 | 
				
			||||||
		/// <param name="cmdText"></param>
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
		/// <param name="cmdParms"></param>
 | 
							/// <param name="cmdParms"></param>
 | 
				
			||||||
		Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
							Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms);
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							/// <param name="cmdText"></param>
 | 
				
			||||||
 | 
							/// <param name="parms"></param>
 | 
				
			||||||
 | 
							/// <returns></returns>
 | 
				
			||||||
 | 
							Task<object> ExecuteScalarAsync(string cmdText, object parms = null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
							/// 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
using FreeSql.Internal.Model;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Linq.Expressions;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
@@ -90,8 +91,8 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			if (index >= 0) field.Append(" as").Append(++index);
 | 
								if (index >= 0) field.Append(" as").Append(++index);
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		internal object ReadAnonymous(ReadAnonymousTypeInfo parent, object[] dr, ref int index) {
 | 
							internal object ReadAnonymous(ReadAnonymousTypeInfo parent, DbDataReader dr, ref int index) {
 | 
				
			||||||
			if (parent.Childs.Any() == false) return dr[++index];
 | 
								if (parent.Childs.Any() == false) return dr.GetValue(++index);
 | 
				
			||||||
			switch (parent.ConsturctorType) {
 | 
								switch (parent.ConsturctorType) {
 | 
				
			||||||
				case ReadAnonymousTypeInfoConsturctorType.Arguments:
 | 
									case ReadAnonymousTypeInfoConsturctorType.Arguments:
 | 
				
			||||||
					var args = new object[parent.Childs.Count];
 | 
										var args = new object[parent.Childs.Count];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,23 +62,19 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			if (isThrowException) throw e;
 | 
								if (isThrowException) throw e;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public List<T> Query<T>(string sql, object parms = null) => Query<T>(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public List<T> Query<T>(string cmdText, object parms = null) => Query<T>(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		public List<T> Query<T>(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							public List<T> Query<T>(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var names = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
 | 
								var names = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
			var ret = new List<T>();
 | 
								var ret = new List<T>();
 | 
				
			||||||
			var type = typeof(T);
 | 
								var type = typeof(T);
 | 
				
			||||||
			var defaultValue = default(T);
 | 
					 | 
				
			||||||
			ExecuteReader(dr => {
 | 
								ExecuteReader(dr => {
 | 
				
			||||||
				if (names.Any() == false)
 | 
									if (names.Any() == false)
 | 
				
			||||||
					for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
 | 
										for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
 | 
				
			||||||
				object[] values = new object[names.Count];
 | 
									ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value);
 | 
				
			||||||
				dr.GetValues(values);
 | 
					 | 
				
			||||||
				var read = Utils.ExecuteArrayRowReadClassOrTuple(type, names, values, 0);
 | 
					 | 
				
			||||||
				ret.Add(read.Value == null ? defaultValue : (T)read.Value);
 | 
					 | 
				
			||||||
			}, cmdType, cmdText, cmdParms);
 | 
								}, cmdType, cmdText, cmdParms);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public void ExecuteReader(Action<DbDataReader> readerHander, string sql, object parms = null) => ExecuteReader(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public void ExecuteReader(Action<DbDataReader> readerHander, string cmdText, object parms = null) => ExecuteReader(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							public void ExecuteReader(Action<DbDataReader> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var dt = DateTime.Now;
 | 
								var dt = DateTime.Now;
 | 
				
			||||||
			var logtxt = new StringBuilder();
 | 
								var logtxt = new StringBuilder();
 | 
				
			||||||
@@ -172,7 +168,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			LoggerException(pool, pc.cmd, ex, dt, logtxt);
 | 
								LoggerException(pool, pc.cmd, ex, dt, logtxt);
 | 
				
			||||||
			pc.cmd.Parameters.Clear();
 | 
								pc.cmd.Parameters.Clear();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public object[][] ExecuteArray(string sql, object parms = null) => ExecuteArray(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public object[][] ExecuteArray(string cmdText, object parms = null) => ExecuteArray(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							public object[][] ExecuteArray(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			List<object[]> ret = new List<object[]>();
 | 
								List<object[]> ret = new List<object[]>();
 | 
				
			||||||
			ExecuteReader(dr => {
 | 
								ExecuteReader(dr => {
 | 
				
			||||||
@@ -182,7 +178,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			}, cmdType, cmdText, cmdParms);
 | 
								}, cmdType, cmdText, cmdParms);
 | 
				
			||||||
			return ret.ToArray();
 | 
								return ret.ToArray();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public DataTable ExecuteDataTable(string sql, object parms = null) => ExecuteDataTable(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public DataTable ExecuteDataTable(string cmdText, object parms = null) => ExecuteDataTable(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							public DataTable ExecuteDataTable(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var ret = new DataTable();
 | 
								var ret = new DataTable();
 | 
				
			||||||
			ExecuteReader(dr => {
 | 
								ExecuteReader(dr => {
 | 
				
			||||||
@@ -194,7 +190,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			}, cmdType, cmdText, cmdParms);
 | 
								}, cmdType, cmdText, cmdParms);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public int ExecuteNonQuery(string sql, object parms = null) => ExecuteNonQuery(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public int ExecuteNonQuery(string cmdText, object parms = null) => ExecuteNonQuery(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							public int ExecuteNonQuery(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var dt = DateTime.Now;
 | 
								var dt = DateTime.Now;
 | 
				
			||||||
			var logtxt = new StringBuilder();
 | 
								var logtxt = new StringBuilder();
 | 
				
			||||||
@@ -219,7 +215,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			pc.cmd.Parameters.Clear();
 | 
								pc.cmd.Parameters.Clear();
 | 
				
			||||||
			return val;
 | 
								return val;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public object ExecuteScalar(string sql, object parms = null) => ExecuteScalar(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public object ExecuteScalar(string cmdText, object parms = null) => ExecuteScalar(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							public object ExecuteScalar(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var dt = DateTime.Now;
 | 
								var dt = DateTime.Now;
 | 
				
			||||||
			var logtxt = new StringBuilder();
 | 
								var logtxt = new StringBuilder();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,25 +9,20 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace FreeSql.Internal.CommonProvider {
 | 
					namespace FreeSql.Internal.CommonProvider {
 | 
				
			||||||
	partial class AdoProvider {
 | 
						partial class AdoProvider {
 | 
				
			||||||
		public Task<List<T>> QueryAsync<T>(string sql, object parms = null) => QueryAsync<T>(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public Task<List<T>> QueryAsync<T>(string cmdText, object parms = null) => QueryAsync<T>(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		async public Task<List<T>> QueryAsync<T>(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							async public Task<List<T>> QueryAsync<T>(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var names = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
 | 
								var names = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);
 | 
				
			||||||
			var ds = new List<object[]>();
 | 
								var ret = new List<T>();
 | 
				
			||||||
			await ExecuteReaderAsync(async dr => {
 | 
								var type = typeof(T);
 | 
				
			||||||
 | 
								await ExecuteReaderAsync(dr => {
 | 
				
			||||||
				if (names.Any() == false)
 | 
									if (names.Any() == false)
 | 
				
			||||||
					for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
 | 
										for (var a = 0; a < dr.FieldCount; a++) names.Add(dr.GetName(a), a);
 | 
				
			||||||
				object[] values = new object[dr.FieldCount];
 | 
									ret.Add((T)Utils.ExecuteArrayRowReadClassOrTuple(type, names, dr, 0).Value);
 | 
				
			||||||
				for (int a = 0; a < values.Length; a++) if (!await dr.IsDBNullAsync(a)) values[a] = await dr.GetFieldValueAsync<object>(a);
 | 
									return Task.CompletedTask;
 | 
				
			||||||
				ds.Add(values);
 | 
					 | 
				
			||||||
			}, cmdType, cmdText, cmdParms);
 | 
								}, cmdType, cmdText, cmdParms);
 | 
				
			||||||
			var ret = new List<T>();
 | 
					 | 
				
			||||||
			foreach (var row in ds) {
 | 
					 | 
				
			||||||
				var read = Utils.ExecuteArrayRowReadClassOrTuple(typeof(T), names, row);
 | 
					 | 
				
			||||||
				ret.Add(read.Value == null ? default(T) : (T) read.Value);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string sql, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, string cmdText, object parms = null) => ExecuteReaderAsync(readerHander, CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							async public Task ExecuteReaderAsync(Func<DbDataReader, Task> readerHander, CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var dt = DateTime.Now;
 | 
								var dt = DateTime.Now;
 | 
				
			||||||
			var logtxt = new StringBuilder();
 | 
								var logtxt = new StringBuilder();
 | 
				
			||||||
@@ -121,7 +116,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			LoggerException(pool, cmd, ex, dt, logtxt);
 | 
								LoggerException(pool, cmd, ex, dt, logtxt);
 | 
				
			||||||
			cmd.Parameters.Clear();
 | 
								cmd.Parameters.Clear();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public Task ExecuteArrayAsync(string sql, object parms = null) => ExecuteArrayAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public Task<object[][]> ExecuteArrayAsync(string cmdText, object parms = null) => ExecuteArrayAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		async public Task<object[][]> ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							async public Task<object[][]> ExecuteArrayAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			List<object[]> ret = new List<object[]>();
 | 
								List<object[]> ret = new List<object[]>();
 | 
				
			||||||
			await ExecuteReaderAsync(async dr => {
 | 
								await ExecuteReaderAsync(async dr => {
 | 
				
			||||||
@@ -131,7 +126,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			}, cmdType, cmdText, cmdParms);
 | 
								}, cmdType, cmdText, cmdParms);
 | 
				
			||||||
			return ret.ToArray();
 | 
								return ret.ToArray();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public Task<DataTable> ExecuteDataTableAsync(string sql, object parms = null) => ExecuteDataTableAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public Task<DataTable> ExecuteDataTableAsync(string cmdText, object parms = null) => ExecuteDataTableAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		async public Task<DataTable> ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							async public Task<DataTable> ExecuteDataTableAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var ret = new DataTable();
 | 
								var ret = new DataTable();
 | 
				
			||||||
			await ExecuteReaderAsync(async dr => {
 | 
								await ExecuteReaderAsync(async dr => {
 | 
				
			||||||
@@ -143,7 +138,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			}, cmdType, cmdText, cmdParms);
 | 
								}, cmdType, cmdText, cmdParms);
 | 
				
			||||||
			return ret;
 | 
								return ret;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public Task<int> ExecuteNonQueryAsync(string sql, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public Task<int> ExecuteNonQueryAsync(string cmdText, object parms = null) => ExecuteNonQueryAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							async public Task<int> ExecuteNonQueryAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var dt = DateTime.Now;
 | 
								var dt = DateTime.Now;
 | 
				
			||||||
			var logtxt = new StringBuilder();
 | 
								var logtxt = new StringBuilder();
 | 
				
			||||||
@@ -168,7 +163,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			cmd.Parameters.Clear();
 | 
								cmd.Parameters.Clear();
 | 
				
			||||||
			return val;
 | 
								return val;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public Task<object> ExecuteScalarAsync(string sql, object parms = null) => ExecuteScalarAsync(CommandType.Text, sql, GetDbParamtersByObject(sql, parms));
 | 
							public Task<object> ExecuteScalarAsync(string cmdText, object parms = null) => ExecuteScalarAsync(CommandType.Text, cmdText, GetDbParamtersByObject(cmdText, parms));
 | 
				
			||||||
		async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
							async public Task<object> ExecuteScalarAsync(CommandType cmdType, string cmdText, params DbParameter[] cmdParms) {
 | 
				
			||||||
			var dt = DateTime.Now;
 | 
								var dt = DateTime.Now;
 | 
				
			||||||
			var logtxt = new StringBuilder();
 | 
								var logtxt = new StringBuilder();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -147,11 +147,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
 | 
								return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
 | 
				
			||||||
				List<TTuple> ret = new List<TTuple>();
 | 
									List<TTuple> ret = new List<TTuple>();
 | 
				
			||||||
				Type type = typeof(TTuple);
 | 
									Type type = typeof(TTuple);
 | 
				
			||||||
				var ds = _orm.Ado.ExecuteArray(CommandType.Text, sql, _params.ToArray());
 | 
									_orm.Ado.ExecuteReader(dr => {
 | 
				
			||||||
				foreach (var dr in ds) {
 | 
					 | 
				
			||||||
					var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
 | 
										var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
 | 
				
			||||||
					ret.Add(read.Value == null ? default(TTuple) : (TTuple)read.Value);
 | 
										ret.Add((TTuple)read.Value);
 | 
				
			||||||
				}
 | 
									}, CommandType.Text, sql, _params.ToArray());
 | 
				
			||||||
				return ret;
 | 
									return ret;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -162,19 +161,40 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
 | 
								return _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
 | 
				
			||||||
				List<TTuple> ret = new List<TTuple>();
 | 
									List<TTuple> ret = new List<TTuple>();
 | 
				
			||||||
				Type type = typeof(TTuple);
 | 
									Type type = typeof(TTuple);
 | 
				
			||||||
				var ds = await _orm.Ado.ExecuteArrayAsync(CommandType.Text, sql, _params.ToArray());
 | 
									await _orm.Ado.ExecuteReaderAsync(dr => {
 | 
				
			||||||
				foreach (var dr in ds) {
 | 
					 | 
				
			||||||
					var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
 | 
										var read = Utils.ExecuteArrayRowReadClassOrTuple(type, null, dr);
 | 
				
			||||||
					ret.Add(read.Value == null ? default(TTuple) : (TTuple)read.Value);
 | 
										ret.Add((TTuple)read.Value);
 | 
				
			||||||
				}
 | 
										return Task.CompletedTask;
 | 
				
			||||||
 | 
									}, CommandType.Text, sql, _params.ToArray());
 | 
				
			||||||
				return ret;
 | 
									return ret;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public List<T1> ToList() {
 | 
							public List<T1> ToList() {
 | 
				
			||||||
			return this.ToListMapReader<T1>(this.GetAllField());
 | 
								var af = this.GetAllFieldExpressionTree();
 | 
				
			||||||
 | 
								var sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
								if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
 | 
				
			||||||
 | 
									List<T1> ret = new List<T1>();
 | 
				
			||||||
 | 
									_orm.Ado.ExecuteReader(dr => {
 | 
				
			||||||
 | 
										ret.Add(af.Read(dr));
 | 
				
			||||||
 | 
									}, CommandType.Text, sql, _params.ToArray());
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public Task<List<T1>> ToListAsync() {
 | 
							async public Task<List<T1>> ToListAsync() {
 | 
				
			||||||
			return this.ToListMapReaderAsync<T1>(this.GetAllField());
 | 
								var af = this.GetAllFieldExpressionTree();
 | 
				
			||||||
 | 
								var sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
								if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
 | 
				
			||||||
 | 
									List<T1> ret = new List<T1>();
 | 
				
			||||||
 | 
									await _orm.Ado.ExecuteReaderAsync(dr => {
 | 
				
			||||||
 | 
										ret.Add(af.Read(dr));
 | 
				
			||||||
 | 
										return Task.CompletedTask;
 | 
				
			||||||
 | 
									}, CommandType.Text, sql, _params.ToArray());
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		public T1 ToOne() {
 | 
							public T1 ToOne() {
 | 
				
			||||||
			this.Limit(1);
 | 
								this.Limit(1);
 | 
				
			||||||
@@ -189,27 +209,30 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			var sql = this.ToSql(af.field);
 | 
								var sql = this.ToSql(af.field);
 | 
				
			||||||
			if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
 | 
								if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var drarr = _orm.Cache.Shell(_cache.key, _cache.seconds, () => _orm.Ado.ExecuteArray(CommandType.Text, sql, _params.ToArray()));
 | 
								return _orm.Cache.Shell(_cache.key, _cache.seconds, () => {
 | 
				
			||||||
			var ret = new List<TReturn>();
 | 
									List<TReturn> ret = new List<TReturn>();
 | 
				
			||||||
			for (var a = 0; a < drarr.Length; a++) {
 | 
									Type type = typeof(TReturn);
 | 
				
			||||||
				var dr = drarr[a];
 | 
									_orm.Ado.ExecuteReader(dr => {
 | 
				
			||||||
				var index = -1;
 | 
										var index = -1;
 | 
				
			||||||
				ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
 | 
										ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
 | 
				
			||||||
			}
 | 
									}, CommandType.Text, sql, _params.ToArray());
 | 
				
			||||||
			return ret;
 | 
									return ret;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		async protected Task<List<TReturn>> ToListMapReaderAsync<TReturn>((ReadAnonymousTypeInfo map, string field) af) {
 | 
							async protected Task<List<TReturn>> ToListMapReaderAsync<TReturn>((ReadAnonymousTypeInfo map, string field) af) {
 | 
				
			||||||
			var sql = this.ToSql(af.field);
 | 
								var sql = this.ToSql(af.field);
 | 
				
			||||||
			if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
 | 
								if (_cache.seconds > 0 && string.IsNullOrEmpty(_cache.key)) _cache.key = $"{sql}{string.Join("|", _params.Select(a => a.Value))}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var drarr = await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, () => _orm.Ado.ExecuteArrayAsync(CommandType.Text, sql, _params.ToArray()));
 | 
								return await _orm.Cache.ShellAsync(_cache.key, _cache.seconds, async () => {
 | 
				
			||||||
			var ret = new List<TReturn>();
 | 
									List<TReturn> ret = new List<TReturn>();
 | 
				
			||||||
			for (var a = 0; a < drarr.Length; a++) {
 | 
									Type type = typeof(TReturn);
 | 
				
			||||||
				var dr = drarr[a];
 | 
									await _orm.Ado.ExecuteReaderAsync(dr => {
 | 
				
			||||||
				var index = -1;
 | 
										var index = -1;
 | 
				
			||||||
				ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
 | 
										ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, dr, ref index));
 | 
				
			||||||
			}
 | 
										return Task.CompletedTask;
 | 
				
			||||||
			return ret;
 | 
									}, CommandType.Text, sql, _params.ToArray());
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) {
 | 
							protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) {
 | 
				
			||||||
			var map = new ReadAnonymousTypeInfo();
 | 
								var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
@@ -219,15 +242,113 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
			_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null);
 | 
								_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null);
 | 
				
			||||||
			return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
								return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		protected (ReadAnonymousTypeInfo map, string field) GetAllField() {
 | 
							static ConcurrentDictionary<Type, ConstructorInfo> _dicConstructor = new ConcurrentDictionary<Type, ConstructorInfo>();
 | 
				
			||||||
			var type = typeof(T1);
 | 
							static ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo> _dicGetAllFieldExpressionTree = new ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo>();
 | 
				
			||||||
			var map = new ReadAnonymousTypeInfo { Consturctor = type.GetConstructor(new Type[0]), ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
 | 
							public class GetAllFieldExpressionTreeInfo {
 | 
				
			||||||
 | 
								public string Field { get; set; }
 | 
				
			||||||
 | 
								public Func<DbDataReader, T1> Read { get; set; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							protected GetAllFieldExpressionTreeInfo GetAllFieldExpressionTree() {
 | 
				
			||||||
 | 
								var key = string.Join("+", _tables.Select(a => $"{a.Table.DbName}-{a.Alias}"));
 | 
				
			||||||
 | 
								return _dicGetAllFieldExpressionTree.GetOrAdd(key, s => {
 | 
				
			||||||
 | 
									var type = _tables.First().Table.Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
 | 
				
			||||||
 | 
									var returnTarget = Expression.Label(type);
 | 
				
			||||||
 | 
									var retExp = Expression.Variable(type, "ret");
 | 
				
			||||||
 | 
									var dataIndexExp = Expression.Variable(typeof(int), "dataIndex");
 | 
				
			||||||
 | 
									var readExp = Expression.Variable(typeof(Utils.RowInfo), "read");
 | 
				
			||||||
 | 
									var readExpValue = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyValue);
 | 
				
			||||||
 | 
									var readExpDataIndex = Expression.MakeMemberAccess(readExp, Utils.RowInfo.PropertyDataIndex);
 | 
				
			||||||
 | 
									var blockExp = new List<Expression>();
 | 
				
			||||||
 | 
									var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
 | 
				
			||||||
 | 
									blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
										Expression.Assign(retExp, Expression.New(ctor, ctor.GetParameters().Select(a => Expression.Default(a.ParameterType)))),
 | 
				
			||||||
 | 
										Expression.Assign(dataIndexExp, Expression.Constant(0))
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									var field = new StringBuilder();
 | 
				
			||||||
 | 
									var dicfield = new Dictionary<string, bool>();
 | 
				
			||||||
 | 
									var tb = _tables.First();
 | 
				
			||||||
 | 
									var index = 0;
 | 
				
			||||||
 | 
									var ps = _tables.First().Table.Properties;
 | 
				
			||||||
 | 
									foreach (var prop in ps.Values) {
 | 
				
			||||||
 | 
										if (tb.Table.ColumnsByCs.TryGetValue(prop.Name, out var col)) { //普通字段
 | 
				
			||||||
 | 
											if (index > 0) field.Append(", ");
 | 
				
			||||||
 | 
											var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
 | 
				
			||||||
 | 
											field.Append(_commonUtils.QuoteReadColumn(col.CsType, $"{tb.Alias}.{quoteName}"));
 | 
				
			||||||
 | 
											++index;
 | 
				
			||||||
 | 
											if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
 | 
				
			||||||
 | 
											else dicfield.Add(quoteName, true);
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											var tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType && a.Alias.Contains(prop.Name)).FirstOrDefault();
 | 
				
			||||||
 | 
											if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == prop.PropertyType).FirstOrDefault();
 | 
				
			||||||
 | 
											if (tb2 == null) continue;
 | 
				
			||||||
 | 
											foreach (var col2 in tb2.Table.Columns.Values) {
 | 
				
			||||||
 | 
												if (index > 0) field.Append(", ");
 | 
				
			||||||
 | 
												var quoteName = _commonUtils.QuoteSqlName(col2.Attribute.Name);
 | 
				
			||||||
 | 
												field.Append(_commonUtils.QuoteReadColumn(col2.CsType, $"{tb2.Alias}.{quoteName}"));
 | 
				
			||||||
 | 
												++index;
 | 
				
			||||||
 | 
												if (dicfield.ContainsKey(quoteName)) field.Append(" as").Append(index);
 | 
				
			||||||
 | 
												else dicfield.Add(quoteName, true);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										//只读到二级属性
 | 
				
			||||||
 | 
										var propGetSetMethod = prop.GetSetMethod();
 | 
				
			||||||
 | 
										Expression readExpAssign = null; //加速缓存
 | 
				
			||||||
 | 
										if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
 | 
				
			||||||
 | 
											Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }),
 | 
				
			||||||
 | 
											Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
										);
 | 
				
			||||||
 | 
										else {
 | 
				
			||||||
 | 
											var proptypeGeneric = prop.PropertyType;
 | 
				
			||||||
 | 
											if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
 | 
				
			||||||
 | 
											if (proptypeGeneric.IsEnum ||
 | 
				
			||||||
 | 
												Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
 | 
				
			||||||
 | 
												Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }),
 | 
				
			||||||
 | 
												Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
											);
 | 
				
			||||||
 | 
											else {
 | 
				
			||||||
 | 
												readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Constant(null, typeof(Dictionary<string, int>)), rowExp, dataIndexExp });
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
											//以下注释部分为【严格读取】,会损失一点性能
 | 
				
			||||||
 | 
											//Expression.IfThen(Expression.Not(Expression.And(
 | 
				
			||||||
 | 
											//	Expression.NotEqual(namesExp, Expression.Constant(null)),
 | 
				
			||||||
 | 
											//	Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))),
 | 
				
			||||||
 | 
											//	Expression.Block(
 | 
				
			||||||
 | 
													Expression.Assign(readExp, readExpAssign),
 | 
				
			||||||
 | 
													Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
 | 
				
			||||||
 | 
														Expression.Assign(dataIndexExp, readExpDataIndex)),
 | 
				
			||||||
 | 
													Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
														Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
 | 
				
			||||||
 | 
														Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
 | 
				
			||||||
 | 
											//	)
 | 
				
			||||||
 | 
											//)
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
										Expression.Return(returnTarget, retExp),
 | 
				
			||||||
 | 
										Expression.Label(returnTarget, Expression.Default(type))
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
									return new GetAllFieldExpressionTreeInfo {
 | 
				
			||||||
 | 
										Field = field.ToString(),
 | 
				
			||||||
 | 
										Read = Expression.Lambda<Func<DbDataReader, T1>>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { rowExp }).Compile()
 | 
				
			||||||
 | 
									};
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							protected (ReadAnonymousTypeInfo map, string field) GetAllFieldReflection() {
 | 
				
			||||||
 | 
								var type = _tables.First().Table.Type;
 | 
				
			||||||
 | 
								var constructor = _dicConstructor.GetOrAdd(type, s => type.GetConstructor(new Type[0]));
 | 
				
			||||||
 | 
								var map = new ReadAnonymousTypeInfo { Consturctor = constructor, ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var field = new StringBuilder();
 | 
								var field = new StringBuilder();
 | 
				
			||||||
			var dicfield = new Dictionary<string, bool>();
 | 
								var dicfield = new Dictionary<string, bool>();
 | 
				
			||||||
			var tb = _tables.First();
 | 
								var tb = _tables.First();
 | 
				
			||||||
			var index = 0;
 | 
								var index = 0;
 | 
				
			||||||
			var ps = type.GetProperties();
 | 
								var ps = _tables.First().Table.Properties;
 | 
				
			||||||
			foreach (var p in ps) {
 | 
								foreach (var p in ps.Values) {
 | 
				
			||||||
				var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name };
 | 
									var child = new ReadAnonymousTypeInfo { Property = p, CsName = p.Name };
 | 
				
			||||||
				if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
 | 
									if (tb.Table.ColumnsByCs.TryGetValue(p.Name, out var col)) { //普通字段
 | 
				
			||||||
					if (index > 0) field.Append(", ");
 | 
										if (index > 0) field.Append(", ");
 | 
				
			||||||
@@ -238,7 +359,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
				
			|||||||
					else dicfield.Add(quoteName, true);
 | 
										else dicfield.Add(quoteName, true);
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault();
 | 
										var tb2 = _tables.Where(a => a.Table.Type == p.PropertyType && a.Alias.Contains(p.Name)).FirstOrDefault();
 | 
				
			||||||
					if (tb2 == null && ps.Where(pw => pw.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault();
 | 
										if (tb2 == null && ps.Where(pw => pw.Value.PropertyType == p.PropertyType).Count() == 1) tb2 = _tables.Where(a => a.Table.Type == p.PropertyType).FirstOrDefault();
 | 
				
			||||||
					if (tb2 == null) continue;
 | 
										if (tb2 == null) continue;
 | 
				
			||||||
					child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]);
 | 
										child.Consturctor = tb2.Table.Type.GetConstructor(new Type[0]);
 | 
				
			||||||
					child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
 | 
										child.ConsturctorType = ReadAnonymousTypeInfoConsturctorType.Properties;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,8 @@ using System;
 | 
				
			|||||||
using System.Collections;
 | 
					using System.Collections;
 | 
				
			||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Linq.Expressions;
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
@@ -111,7 +113,7 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			return ret.ToArray();
 | 
								return ret.ToArray();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
 | 
							internal static Dictionary<Type, bool> dicExecuteArrayRowReadClassOrTuple = new Dictionary<Type, bool> {
 | 
				
			||||||
			[typeof(bool)] = true,
 | 
								[typeof(bool)] = true,
 | 
				
			||||||
			[typeof(sbyte)] = true,
 | 
								[typeof(sbyte)] = true,
 | 
				
			||||||
			[typeof(short)] = true,
 | 
								[typeof(short)] = true,
 | 
				
			||||||
@@ -164,7 +166,7 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			[typeof(JObject)] = true,
 | 
								[typeof(JObject)] = true,
 | 
				
			||||||
			[typeof(JArray)] = true,
 | 
								[typeof(JArray)] = true,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		static ConcurrentDictionary<Type, Func<Type, Dictionary<string, int>, object[], int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary<Type, Func<Type, Dictionary<string, int>, object[], int, RowInfo>>();
 | 
							static ConcurrentDictionary<Type, Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>> _dicExecuteArrayRowReadClassOrTuple = new ConcurrentDictionary<Type, Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>();
 | 
				
			||||||
		internal class RowInfo {
 | 
							internal class RowInfo {
 | 
				
			||||||
			public object Value { get; set; }
 | 
								public object Value { get; set; }
 | 
				
			||||||
			public int DataIndex { get; set; }
 | 
								public int DataIndex { get; set; }
 | 
				
			||||||
@@ -176,17 +178,18 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value");
 | 
								public static PropertyInfo PropertyValue = typeof(RowInfo).GetProperty("Value");
 | 
				
			||||||
			public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
 | 
								public static PropertyInfo PropertyDataIndex = typeof(RowInfo).GetProperty("DataIndex");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, Dictionary<string, int> names, object[] row, int dataIndex = 0) {
 | 
							internal static MethodInfo MethodDataReaderGetValue = typeof(DbDataReader).GetMethod("GetValue");
 | 
				
			||||||
 | 
							internal static RowInfo ExecuteArrayRowReadClassOrTuple(Type type, Dictionary<string, int> names, DbDataReader row, int dataIndex = 0) {
 | 
				
			||||||
			var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(type, s => {
 | 
								var func = _dicExecuteArrayRowReadClassOrTuple.GetOrAdd(type, s => {
 | 
				
			||||||
				var returnTarget = Expression.Label(typeof(RowInfo));
 | 
									var returnTarget = Expression.Label(typeof(RowInfo));
 | 
				
			||||||
				var typeExp = Expression.Parameter(typeof(Type), "type");
 | 
									var typeExp = Expression.Parameter(typeof(Type), "type");
 | 
				
			||||||
				var namesExp = Expression.Parameter(typeof(Dictionary<string, int>), "names");
 | 
									var namesExp = Expression.Parameter(typeof(Dictionary<string, int>), "names");
 | 
				
			||||||
				var rowExp = Expression.Parameter(typeof(object[]), "row");
 | 
									var rowExp = Expression.Parameter(typeof(DbDataReader), "row");
 | 
				
			||||||
				var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex");
 | 
									var dataIndexExp = Expression.Parameter(typeof(int), "dataIndex");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (type.IsArray) return Expression.Lambda<Func<Type, Dictionary<string, int>, object[], int, RowInfo>>(
 | 
									if (type.IsArray) return Expression.Lambda<Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>(
 | 
				
			||||||
					Expression.New(RowInfo.Constructor,
 | 
										Expression.New(RowInfo.Constructor,
 | 
				
			||||||
						Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.ArrayAccess(rowExp, dataIndexExp) }), 
 | 
											Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), 
 | 
				
			||||||
						Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
											Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
					), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
										), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -194,9 +197,9 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				if (typeGeneric.FullName.StartsWith("System.Nullable`1[")) typeGeneric = type.GenericTypeArguments.First();
 | 
									if (typeGeneric.FullName.StartsWith("System.Nullable`1[")) typeGeneric = type.GenericTypeArguments.First();
 | 
				
			||||||
				if (typeGeneric.IsEnum ||
 | 
									if (typeGeneric.IsEnum ||
 | 
				
			||||||
					dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
 | 
										dicExecuteArrayRowReadClassOrTuple.ContainsKey(typeGeneric))
 | 
				
			||||||
					return Expression.Lambda<Func<Type, Dictionary<string, int>, object[], int, RowInfo>>(
 | 
										return Expression.Lambda<Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>(
 | 
				
			||||||
					Expression.New(RowInfo.Constructor,
 | 
										Expression.New(RowInfo.Constructor,
 | 
				
			||||||
						Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.ArrayAccess(rowExp, dataIndexExp) }),
 | 
											Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }),
 | 
				
			||||||
						Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
											Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
					), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
										), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -211,13 +214,32 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
						var fields = type.GetFields();
 | 
											var fields = type.GetFields();
 | 
				
			||||||
						foreach (var field in fields) {
 | 
											foreach (var field in fields) {
 | 
				
			||||||
 | 
												Expression read2ExpAssign = null; //加速缓存
 | 
				
			||||||
 | 
												if (field.FieldType.IsArray) read2ExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
 | 
													Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }),
 | 
				
			||||||
 | 
													Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
												);
 | 
				
			||||||
 | 
												else {
 | 
				
			||||||
 | 
													var fieldtypeGeneric = field.FieldType;
 | 
				
			||||||
 | 
													if (fieldtypeGeneric.FullName.StartsWith("System.Nullable`1[")) fieldtypeGeneric = fieldtypeGeneric.GenericTypeArguments.First();
 | 
				
			||||||
 | 
													if (fieldtypeGeneric.IsEnum ||
 | 
				
			||||||
 | 
														dicExecuteArrayRowReadClassOrTuple.ContainsKey(fieldtypeGeneric)) read2ExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
 | 
														Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(field.FieldType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }),
 | 
				
			||||||
 | 
														Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
													);
 | 
				
			||||||
 | 
													else {
 | 
				
			||||||
 | 
														read2ExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(field.FieldType), namesExp, rowExp, dataIndexExp });
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
							block2Exp.AddRange(new Expression[] {
 | 
												block2Exp.AddRange(new Expression[] {
 | 
				
			||||||
								//Expression.TryCatch(Expression.Block(
 | 
													//Expression.TryCatch(Expression.Block(
 | 
				
			||||||
								//	typeof(void),
 | 
													//	typeof(void),
 | 
				
			||||||
									Expression.Assign(read2Exp, Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(field.FieldType), namesExp, rowExp, dataIndexExp })),
 | 
														Expression.Assign(read2Exp, read2ExpAssign),
 | 
				
			||||||
									Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), 
 | 
														Expression.IfThen(Expression.GreaterThan(read2ExpDataIndex, dataIndexExp), 
 | 
				
			||||||
										Expression.Assign(dataIndexExp, read2ExpDataIndex)),
 | 
															Expression.Assign(dataIndexExp, read2ExpDataIndex)),
 | 
				
			||||||
									Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType))
 | 
														Expression.IfThenElse(Expression.Equal(read2ExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
															Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Default(field.FieldType)),
 | 
				
			||||||
 | 
															Expression.Assign(Expression.MakeMemberAccess(ret2Exp, field), Expression.Convert(read2ExpValue, field.FieldType)))
 | 
				
			||||||
								//), 
 | 
													//), 
 | 
				
			||||||
								//Expression.Catch(typeof(Exception), Expression.Block(
 | 
													//Expression.Catch(typeof(Exception), Expression.Block(
 | 
				
			||||||
								//		Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))),
 | 
													//		Expression.IfThen(Expression.Equal(read2ExpDataIndex, Expression.Constant(0)), Expression.Throw(Expression.Constant(new Exception(field.Name + "," + 0)))),
 | 
				
			||||||
@@ -233,16 +255,16 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
							Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)),
 | 
												Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, Expression.Convert(ret2Exp, typeof(object)), dataIndexExp)),
 | 
				
			||||||
							Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
 | 
												Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
 | 
				
			||||||
						});
 | 
											});
 | 
				
			||||||
						return Expression.Lambda<Func<Type, Dictionary<string, int>, object[], int, RowInfo>>(
 | 
											return Expression.Lambda<Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>(
 | 
				
			||||||
							Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
												Expression.Block(new[] { ret2Exp, read2Exp }, block2Exp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					var rowLenExp = Expression.ArrayLength(rowExp);
 | 
										var rowLenExp = Expression.ArrayLength(rowExp);
 | 
				
			||||||
					return Expression.Lambda<Func<Type, Dictionary<string, int>, object[], int, RowInfo>>(
 | 
										return Expression.Lambda<Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>(
 | 
				
			||||||
						Expression.Block(
 | 
											Expression.Block(
 | 
				
			||||||
							Expression.IfThen(
 | 
												Expression.IfThen(
 | 
				
			||||||
								Expression.LessThan(dataIndexExp, rowLenExp),
 | 
													Expression.LessThan(dataIndexExp, rowLenExp),
 | 
				
			||||||
									Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, 
 | 
														Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, 
 | 
				
			||||||
										Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.ArrayAccess(rowExp, dataIndexExp) }), 
 | 
															Expression.Call(MethodGetDataReaderValue, new Expression[] { typeExp, Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }), 
 | 
				
			||||||
										Expression.Add(dataIndexExp, Expression.Constant(1))))
 | 
															Expression.Add(dataIndexExp, Expression.Constant(1))))
 | 
				
			||||||
							),
 | 
												),
 | 
				
			||||||
							Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
 | 
												Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
 | 
				
			||||||
@@ -250,14 +272,14 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (type == typeof(object) && names != null) {
 | 
									if (type == typeof(object) && names != null) {
 | 
				
			||||||
					Func<Type, Dictionary<string, int>, object[], int, RowInfo> dynamicFunc = (type2, names2, row2, dataindex2) => {
 | 
										Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo> dynamicFunc = (type2, names2, row2, dataindex2) => {
 | 
				
			||||||
						dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
 | 
											dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写
 | 
				
			||||||
						var expandodic = (IDictionary<string, object>)expando;
 | 
											var expandodic = (IDictionary<string, object>)expando;
 | 
				
			||||||
						foreach (var name in names2)
 | 
											foreach (var name in names2)
 | 
				
			||||||
							expandodic.Add(name.Key, row2[name.Value]);
 | 
												expandodic.Add(name.Key, row2.GetValue(name.Value));
 | 
				
			||||||
						return new RowInfo(expando, names2.Count);
 | 
											return new RowInfo(expando, names2.Count);
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
					return dynamicFunc;// Expression.Lambda<Func<Type, Dictionary<string, int>, object[], int, RowInfo>>(null);
 | 
										return dynamicFunc;// Expression.Lambda<Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>(null);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//类注入属性
 | 
									//类注入属性
 | 
				
			||||||
@@ -265,42 +287,108 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
				var readExp = Expression.Variable(typeof(RowInfo), "read");
 | 
									var readExp = Expression.Variable(typeof(RowInfo), "read");
 | 
				
			||||||
				var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue);
 | 
									var readExpValue = Expression.MakeMemberAccess(readExp, RowInfo.PropertyValue);
 | 
				
			||||||
				var readExpDataIndex = Expression.MakeMemberAccess(readExp, RowInfo.PropertyDataIndex);
 | 
									var readExpDataIndex = Expression.MakeMemberAccess(readExp, RowInfo.PropertyDataIndex);
 | 
				
			||||||
 | 
									var readExpValueParms = new List<ParameterExpression>();
 | 
				
			||||||
 | 
									var readExpsIndex = Expression.Variable(typeof(int), "readsIndex");
 | 
				
			||||||
				var tryidxExp = Expression.Variable(typeof(int), "tryidx");
 | 
									var tryidxExp = Expression.Variable(typeof(int), "tryidx");
 | 
				
			||||||
				var blockExp = new List<Expression>();
 | 
									var blockExp = new List<Expression>();
 | 
				
			||||||
				blockExp.Add(Expression.Assign(retExp, Expression.New(type.GetConstructor(new Type[0]))));
 | 
									var ctor = type.GetConstructor(new Type[0]) ?? type.GetConstructors().First();
 | 
				
			||||||
 | 
									var ctorParms = ctor.GetParameters();
 | 
				
			||||||
 | 
									if (ctorParms.Length > 0) {
 | 
				
			||||||
 | 
										foreach(var ctorParm in ctorParms) {
 | 
				
			||||||
 | 
											Expression readExpAssign = null; //加速缓存
 | 
				
			||||||
 | 
											if (ctorParm.ParameterType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
 | 
												Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
 | 
				
			||||||
 | 
												Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
											);
 | 
				
			||||||
 | 
											else {
 | 
				
			||||||
 | 
												var proptypeGeneric = ctorParm.ParameterType;
 | 
				
			||||||
 | 
												if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
 | 
				
			||||||
 | 
												if (proptypeGeneric.IsEnum ||
 | 
				
			||||||
 | 
													dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
 | 
													Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(ctorParm.ParameterType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp) }),
 | 
				
			||||||
 | 
													Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
												);
 | 
				
			||||||
 | 
												else {
 | 
				
			||||||
 | 
													readExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
 | 
														Expression.MakeMemberAccess(Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(ctorParm.ParameterType), namesExp, rowExp, dataIndexExp }), RowInfo.PropertyValue),
 | 
				
			||||||
 | 
														Expression.Add(dataIndexExp, Expression.Constant(1)));
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											var varctorParm = Expression.Variable(ctorParm.ParameterType, $"ctorParm{ctorParm.Name}");
 | 
				
			||||||
 | 
											readExpValueParms.Add(varctorParm);
 | 
				
			||||||
 | 
											blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
												Expression.Assign(tryidxExp, dataIndexExp),
 | 
				
			||||||
 | 
												//以下注释部分为【严格读取】,会损失一点性能
 | 
				
			||||||
 | 
												//Expression.IfThen(Expression.Not(Expression.And(
 | 
				
			||||||
 | 
												//	Expression.NotEqual(namesExp, Expression.Constant(null)),
 | 
				
			||||||
 | 
												//	Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))),
 | 
				
			||||||
 | 
												//	Expression.Block(
 | 
				
			||||||
 | 
														Expression.Assign(readExp, readExpAssign),
 | 
				
			||||||
 | 
														Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
 | 
				
			||||||
 | 
															Expression.Assign(dataIndexExp, readExpDataIndex)),
 | 
				
			||||||
 | 
														Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
															Expression.Assign(varctorParm, Expression.Default(ctorParm.ParameterType)),
 | 
				
			||||||
 | 
															Expression.Assign(varctorParm, Expression.Convert(readExpValue, ctorParm.ParameterType)))
 | 
				
			||||||
 | 
												//	)
 | 
				
			||||||
 | 
												//)
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										blockExp.Add(Expression.Assign(retExp, Expression.New(ctor, readExpValueParms)));
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										blockExp.Add(Expression.Assign(retExp, Expression.New(ctor)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				var props = type.GetProperties();
 | 
										var props = type.GetProperties();
 | 
				
			||||||
				foreach (var prop in props) {
 | 
										foreach (var prop in props) {
 | 
				
			||||||
					var propGetSetMethod = prop.GetSetMethod();
 | 
											var propGetSetMethod = prop.GetSetMethod();
 | 
				
			||||||
					blockExp.AddRange(new Expression[] {
 | 
											Expression readExpAssign = null; //加速缓存
 | 
				
			||||||
						Expression.Assign(tryidxExp, dataIndexExp),
 | 
											if (prop.PropertyType.IsArray) readExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
						Expression.IfThen(Expression.Not(Expression.And(
 | 
												Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }),
 | 
				
			||||||
							Expression.NotEqual(namesExp, Expression.Constant(null)),
 | 
												Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
							Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))),
 | 
											);
 | 
				
			||||||
							Expression.Block(
 | 
											else {
 | 
				
			||||||
								//Expression.Assign(tryidxExp, Expression.Call(namesExp, namesExp Expression.Constant(prop.Name))),
 | 
												var proptypeGeneric = prop.PropertyType;
 | 
				
			||||||
								Expression.Assign(readExp, Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), namesExp, rowExp, tryidxExp })),
 | 
												if (proptypeGeneric.FullName.StartsWith("System.Nullable`1[")) proptypeGeneric = proptypeGeneric.GenericTypeArguments.First();
 | 
				
			||||||
								Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp), 
 | 
												if (proptypeGeneric.IsEnum ||
 | 
				
			||||||
									Expression.Assign(dataIndexExp, readExpDataIndex)),
 | 
													dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(RowInfo.Constructor,
 | 
				
			||||||
								Expression.IfThen(Expression.NotEqual(readExpValue, Expression.Constant(null)), 
 | 
													Expression.Call(MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, MethodDataReaderGetValue, dataIndexExp)  /*Expression.ArrayAccess(rowExp, dataIndexExp)*/ }),
 | 
				
			||||||
									Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
 | 
													Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
							)
 | 
												);
 | 
				
			||||||
						)
 | 
												else {
 | 
				
			||||||
					});
 | 
													continue;
 | 
				
			||||||
 | 
													readExpAssign = Expression.Call(MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(prop.PropertyType), namesExp, rowExp, tryidxExp });
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
												Expression.Assign(tryidxExp, dataIndexExp),
 | 
				
			||||||
 | 
												//以下注释部分为【严格读取】,会损失一点性能
 | 
				
			||||||
 | 
												//Expression.IfThen(Expression.Not(Expression.And(
 | 
				
			||||||
 | 
												//	Expression.NotEqual(namesExp, Expression.Constant(null)),
 | 
				
			||||||
 | 
												//	Expression.Not(Expression.Call(namesExp, namesExp.Type.GetMethod("TryGetValue"), Expression.Constant(prop.Name), tryidxExp)))),
 | 
				
			||||||
 | 
												//	Expression.Block(
 | 
				
			||||||
 | 
														Expression.Assign(readExp, readExpAssign),
 | 
				
			||||||
 | 
														Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
 | 
				
			||||||
 | 
															Expression.Assign(dataIndexExp, readExpDataIndex)),
 | 
				
			||||||
 | 
														Expression.IfThenElse(Expression.Equal(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
															Expression.Call(retExp, propGetSetMethod, Expression.Default(prop.PropertyType)),
 | 
				
			||||||
 | 
															Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)))
 | 
				
			||||||
 | 
												//	)
 | 
				
			||||||
 | 
												//)
 | 
				
			||||||
 | 
											});
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				blockExp.AddRange(new Expression[] {
 | 
									blockExp.AddRange(new Expression[] {
 | 
				
			||||||
					Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
 | 
										Expression.Return(returnTarget, Expression.New(RowInfo.Constructor, retExp, dataIndexExp)),
 | 
				
			||||||
					Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
 | 
										Expression.Label(returnTarget, Expression.Default(typeof(RowInfo)))
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
				return Expression.Lambda<Func<Type, Dictionary<string, int>, object[], int, RowInfo>>(
 | 
									return Expression.Lambda<Func<Type, Dictionary<string, int>, DbDataReader, int, RowInfo>>(
 | 
				
			||||||
					Expression.Block(new[] { retExp, readExp, tryidxExp }, blockExp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
										Expression.Block(new[] { retExp, readExp, tryidxExp, readExpsIndex }.Concat(readExpValueParms), blockExp), new[] { typeExp, namesExp, rowExp, dataIndexExp }).Compile();
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return func(type, names, row, dataIndex);
 | 
								return func(type, names, row, dataIndex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
 | 
							internal static MethodInfo MethodExecuteArrayRowReadClassOrTuple = typeof(Utils).GetMethod("ExecuteArrayRowReadClassOrTuple", BindingFlags.Static | BindingFlags.NonPublic);
 | 
				
			||||||
		static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic);
 | 
							internal static MethodInfo MethodGetDataReaderValue = typeof(Utils).GetMethod("GetDataReaderValue", BindingFlags.Static | BindingFlags.NonPublic);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static ConcurrentDictionary<string, Action<object, object>> _dicFillPropertyValue = new ConcurrentDictionary<string, Action<object, object>>();
 | 
							static ConcurrentDictionary<string, Action<object, object>> _dicFillPropertyValue = new ConcurrentDictionary<string, Action<object, object>>();
 | 
				
			||||||
		internal static void FillPropertyValue(object info, string memberAccessPath, object value) {
 | 
							internal static void FillPropertyValue(object info, string memberAccessPath, object value) {
 | 
				
			||||||
@@ -322,11 +410,19 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
			act(info, value);
 | 
								act(info, value);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static ConcurrentDictionary<Type, Func<object, object>> _dicGetDataReaderValue = new ConcurrentDictionary<Type, Func<object, object>>();
 | 
							static ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>> _dicGetDataReaderValue = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, Func<object, object>>>();
 | 
				
			||||||
 | 
							static MethodInfo MethodArrayGetValue = typeof(Array).GetMethod("GetValue", new[] { typeof(int) });
 | 
				
			||||||
 | 
							static MethodInfo MethodMygisGeometryParse = typeof(MygisGeometry).GetMethod("Parse", new[] { typeof(string) });
 | 
				
			||||||
 | 
							static MethodInfo MethodGuidParse = typeof(Guid).GetMethod("Parse", new[] { typeof(string) });
 | 
				
			||||||
 | 
							static MethodInfo MethodEnumParse = typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) });
 | 
				
			||||||
 | 
							static MethodInfo MethodToString = typeof(string).GetMethod("Concat", new[] { typeof(object) });
 | 
				
			||||||
 | 
							static MethodInfo MethodConvertChangeType = typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) });
 | 
				
			||||||
 | 
							static MethodInfo MethodTimeSpanFromSeconds = typeof(TimeSpan).GetMethod("FromSeconds");
 | 
				
			||||||
 | 
							static MethodInfo MethodDoubleParse = typeof(double).GetMethod("Parse", new[] { typeof(string) });
 | 
				
			||||||
		internal static object GetDataReaderValue(Type type, object value) {
 | 
							internal static object GetDataReaderValue(Type type, object value) {
 | 
				
			||||||
			if (value == null || value == DBNull.Value) return null;
 | 
								if (value == null || value == DBNull.Value) return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var func = _dicGetDataReaderValue.GetOrAdd(type, k => {
 | 
								var func = _dicGetDataReaderValue.GetOrAdd(type, k1 => new ConcurrentDictionary<Type, Func<object, object>>()).GetOrAdd(value.GetType(), valueType => {
 | 
				
			||||||
				var returnTarget = Expression.Label(typeof(object));
 | 
									var returnTarget = Expression.Label(typeof(object));
 | 
				
			||||||
				var parmExp = Expression.Parameter(typeof(object), "value");
 | 
									var parmExp = Expression.Parameter(typeof(object), "value");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -334,94 +430,90 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if (type.IsArray) {
 | 
									if (type.IsArray) {
 | 
				
			||||||
					var elementType = type.GetElementType();
 | 
										var elementType = type.GetElementType();
 | 
				
			||||||
					var valueArr = value as Array;
 | 
										if (elementType == valueType.GetElementType()) return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (elementType == valueArr.GetType().GetElementType()) return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
										var ret = Expression.Variable(type, "ret");
 | 
				
			||||||
 | 
										var arr = Expression.Variable(valueType, "arr");
 | 
				
			||||||
					var arr = Expression.Variable(type, "arr");
 | 
					 | 
				
			||||||
					var arrlen = Expression.Variable(typeof(int), "arrlen");
 | 
										var arrlen = Expression.Variable(typeof(int), "arrlen");
 | 
				
			||||||
					var x = Expression.Variable(typeof(int), "x");
 | 
										var x = Expression.Variable(typeof(int), "x");
 | 
				
			||||||
 | 
										var readval = Expression.Variable(typeof(object), "readval");
 | 
				
			||||||
					var label = Expression.Label(typeof(int));
 | 
										var label = Expression.Label(typeof(int));
 | 
				
			||||||
					var ret = Expression.NewArrayBounds(elementType, arrlen);
 | 
					 | 
				
			||||||
					return Expression.Lambda<Func<object, object>>(
 | 
										return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
						Expression.Block(
 | 
											Expression.Block(
 | 
				
			||||||
							new[] { arr, arrlen, x },
 | 
												new[] { ret, arr, arrlen, readval, x },
 | 
				
			||||||
							Expression.Assign(arr, Expression.Convert(parmExp, type)),
 | 
												Expression.Assign(arr, Expression.TypeAs(parmExp, valueType)),
 | 
				
			||||||
							Expression.Assign(arrlen, Expression.ArrayLength(arr)),
 | 
												Expression.Assign(arrlen, Expression.ArrayLength(arr)),
 | 
				
			||||||
							Expression.Assign(x, Expression.Constant(0)),
 | 
												Expression.Assign(x, Expression.Constant(0)),
 | 
				
			||||||
							ret,
 | 
												Expression.Assign(ret, Expression.NewArrayBounds(elementType, arrlen)),
 | 
				
			||||||
							Expression.Loop(
 | 
												Expression.Loop(
 | 
				
			||||||
								Expression.IfThenElse(
 | 
													Expression.IfThenElse(
 | 
				
			||||||
									Expression.LessThan(x, arrlen),
 | 
														Expression.LessThan(x, arrlen),
 | 
				
			||||||
									Expression.Block(
 | 
														Expression.Block(
 | 
				
			||||||
										Expression.Assign(
 | 
															Expression.Assign(readval, Expression.Call(
 | 
				
			||||||
											Expression.ArrayAccess(ret, x), 
 | 
																MethodGetDataReaderValue,
 | 
				
			||||||
											Expression.Call(
 | 
																Expression.Constant(elementType, typeof(Type)),
 | 
				
			||||||
												MethodGetDataReaderValue,
 | 
																Expression.Convert(Expression.ArrayAccess(arr, x), typeof(object))
 | 
				
			||||||
												Expression.Constant(elementType, typeof(Type)),
 | 
															)),
 | 
				
			||||||
												Expression.ArrayAccess(arr, x)
 | 
															Expression.IfThenElse(
 | 
				
			||||||
											)
 | 
																Expression.Equal(readval, Expression.Constant(null)),
 | 
				
			||||||
 | 
																Expression.Assign(Expression.ArrayAccess(ret, x), Expression.Default(elementType)),
 | 
				
			||||||
 | 
																Expression.Assign(Expression.ArrayAccess(ret, x), Expression.Convert(readval, elementType))
 | 
				
			||||||
										),
 | 
															),
 | 
				
			||||||
										Expression.PostIncrementAssign(x)
 | 
															Expression.PostIncrementAssign(x)
 | 
				
			||||||
									),
 | 
														),
 | 
				
			||||||
									Expression.Break(label, x)
 | 
														Expression.Break(label, x)
 | 
				
			||||||
								),
 | 
													),
 | 
				
			||||||
								label
 | 
													label
 | 
				
			||||||
							)
 | 
												),
 | 
				
			||||||
 | 
												Expression.Return(returnTarget, ret),
 | 
				
			||||||
 | 
												Expression.Label(returnTarget, Expression.Default(typeof(object)))
 | 
				
			||||||
						), parmExp).Compile();
 | 
											), parmExp).Compile();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (type.FullName.StartsWith("System.Nullable`1[")) type = type.GenericTypeArguments.First();
 | 
									if (type.FullName.StartsWith("System.Nullable`1[")) type = type.GenericTypeArguments.First();
 | 
				
			||||||
				if (type.IsEnum) return Expression.Lambda<Func<object, object>>(
 | 
									if (type.IsEnum) return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
					Expression.Call(
 | 
										Expression.Call(
 | 
				
			||||||
						typeof(Enum).GetMethod("Parse", new[] { typeof(Type), typeof(string), typeof(bool) }),
 | 
											MethodEnumParse,
 | 
				
			||||||
						Expression.Constant(type, typeof(Type)),
 | 
											Expression.Constant(type, typeof(Type)),
 | 
				
			||||||
						Expression.Convert(parmExp, typeof(string)),
 | 
											Expression.Call(MethodToString, parmExp),
 | 
				
			||||||
						Expression.Constant(true, typeof(bool))
 | 
											Expression.Constant(true, typeof(bool))
 | 
				
			||||||
					) , parmExp).Compile();
 | 
										) , parmExp).Compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				switch (type.FullName) {
 | 
									switch (type.FullName) {
 | 
				
			||||||
					case "System.Guid":
 | 
										case "System.Guid":
 | 
				
			||||||
						if (value.GetType() != type) return Expression.Lambda<Func<object, object>>(
 | 
											if (valueType != type) return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.Block(
 | 
												Expression.Convert(Expression.Call(MethodGuidParse, Expression.Convert(parmExp, typeof(string))), typeof(object))
 | 
				
			||||||
								Expression.TryCatch(
 | 
												, parmExp).Compile();
 | 
				
			||||||
									Expression.Return(returnTarget, Expression.Call(typeof(Guid).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string)))),
 | 
					 | 
				
			||||||
									Expression.Catch(typeof(Exception), 
 | 
					 | 
				
			||||||
										Expression.Return(returnTarget, Expression.Constant(Guid.Empty)))
 | 
					 | 
				
			||||||
								),
 | 
					 | 
				
			||||||
								Expression.Label(returnTarget, Expression.Default(type))
 | 
					 | 
				
			||||||
							), parmExp).Compile();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
											return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					case "MygisPoint": return Expression.Lambda<Func<object, object>>(
 | 
										case "MygisPoint": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.TypeAs(
 | 
												Expression.TypeAs(
 | 
				
			||||||
								Expression.Call(typeof(MygisPoint).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))),
 | 
													Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))),
 | 
				
			||||||
								typeof(MygisPoint)
 | 
													typeof(MygisPoint)
 | 
				
			||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "MygisLineString": return Expression.Lambda<Func<object, object>>(
 | 
										case "MygisLineString": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.TypeAs(
 | 
												Expression.TypeAs(
 | 
				
			||||||
								Expression.Call(typeof(MygisLineString).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), 
 | 
													Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), 
 | 
				
			||||||
								typeof(MygisLineString)
 | 
													typeof(MygisLineString)
 | 
				
			||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "MygisPolygon": return Expression.Lambda<Func<object, object>>(
 | 
										case "MygisPolygon": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.TypeAs(
 | 
												Expression.TypeAs(
 | 
				
			||||||
								Expression.Call(typeof(MygisPolygon).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), 
 | 
													Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), 
 | 
				
			||||||
								typeof(MygisPolygon)
 | 
													typeof(MygisPolygon)
 | 
				
			||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "MygisMultiPoint": return Expression.Lambda<Func<object, object>>(
 | 
										case "MygisMultiPoint": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.TypeAs(
 | 
												Expression.TypeAs(
 | 
				
			||||||
								Expression.Call(typeof(MygisMultiPoint).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), 
 | 
													Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), 
 | 
				
			||||||
								typeof(MygisMultiPoint)
 | 
													typeof(MygisMultiPoint)
 | 
				
			||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "MygisMultiLineString": return Expression.Lambda<Func<object, object>>(
 | 
										case "MygisMultiLineString": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.TypeAs(
 | 
												Expression.TypeAs(
 | 
				
			||||||
								Expression.Call(typeof(MygisMultiLineString).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), 
 | 
													Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), 
 | 
				
			||||||
								typeof(MygisMultiLineString)
 | 
													typeof(MygisMultiLineString)
 | 
				
			||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "MygisMultiPolygon": return Expression.Lambda<Func<object, object>>(
 | 
										case "MygisMultiPolygon": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
							Expression.TypeAs(
 | 
												Expression.TypeAs(
 | 
				
			||||||
								Expression.Call(typeof(MygisMultiPolygon).GetMethod("Parse"), Expression.Convert(parmExp, typeof(string))), 
 | 
													Expression.Call(MethodMygisGeometryParse, Expression.Convert(parmExp, typeof(string))), 
 | 
				
			||||||
								typeof(MygisMultiPolygon)
 | 
													typeof(MygisMultiPolygon)
 | 
				
			||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "Newtonsoft.Json.Linq.JToken": return Expression.Lambda<Func<object, object>>(
 | 
										case "Newtonsoft.Json.Linq.JToken": return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
@@ -441,20 +533,58 @@ namespace FreeSql.Internal {
 | 
				
			|||||||
							), parmExp).Compile();
 | 
												), parmExp).Compile();
 | 
				
			||||||
					case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
										case "Npgsql.LegacyPostgis.PostgisGeometry": return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (type != value.GetType()) {
 | 
									if (type != valueType) {
 | 
				
			||||||
					if (type.FullName == "System.TimeSpan") return Expression.Lambda<Func<object, object>>(
 | 
										if (type.FullName == "System.TimeSpan") return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
						Expression.Call(
 | 
											Expression.Convert(Expression.Call(
 | 
				
			||||||
							typeof(TimeSpan).GetMethod("FromSeconds"),
 | 
												MethodTimeSpanFromSeconds,
 | 
				
			||||||
							Expression.Call(typeof(double).GetMethod("Parse", new[] { typeof(string) }), Expression.Convert(parmExp, typeof(string)))
 | 
												Expression.Call(MethodDoubleParse, Expression.Call(MethodToString, parmExp))
 | 
				
			||||||
						), parmExp).Compile();
 | 
											), typeof(object)), parmExp).Compile();
 | 
				
			||||||
					return Expression.Lambda<Func<object, object>>(
 | 
										return Expression.Lambda<Func<object, object>>(
 | 
				
			||||||
						Expression.Call(typeof(Convert).GetMethod("ChangeType", new[] { typeof(object), typeof(Type) }), parmExp, Expression.Constant(type, typeof(Type)))
 | 
											Expression.Call(MethodConvertChangeType, parmExp, Expression.Constant(type, typeof(Type)))
 | 
				
			||||||
					, parmExp).Compile();
 | 
										, parmExp).Compile();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
									return Expression.Lambda<Func<object, object>>(parmExp, parmExp).Compile();
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
			return func(value);
 | 
								return func(value);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							internal static object GetDataReaderValue22(Type type, object value) {
 | 
				
			||||||
 | 
								if (value == null || value == DBNull.Value) return null;
 | 
				
			||||||
 | 
								if (type.FullName == "System.Byte[]") return value;
 | 
				
			||||||
 | 
								if (type.IsArray) {
 | 
				
			||||||
 | 
									var elementType = type.GetElementType();
 | 
				
			||||||
 | 
									var valueArr = value as Array;
 | 
				
			||||||
 | 
									if (elementType == valueArr.GetType().GetElementType()) return value;
 | 
				
			||||||
 | 
									var len = valueArr.GetLength(0);
 | 
				
			||||||
 | 
									var ret = Array.CreateInstance(elementType, len);
 | 
				
			||||||
 | 
									for (var a = 0; a < len; a++) {
 | 
				
			||||||
 | 
										var item = valueArr.GetValue(a);
 | 
				
			||||||
 | 
										ret.SetValue(GetDataReaderValue(elementType, item), a);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return ret;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (type.FullName.StartsWith("System.Nullable`1[")) type = type.GenericTypeArguments.First();
 | 
				
			||||||
 | 
								if (type.IsEnum) return Enum.Parse(type, string.Concat(value), true);
 | 
				
			||||||
 | 
								switch (type.FullName) {
 | 
				
			||||||
 | 
									case "System.Guid":
 | 
				
			||||||
 | 
										if (value.GetType() != type) return Guid.TryParse(string.Concat(value), out var tryguid) ? tryguid : Guid.Empty;
 | 
				
			||||||
 | 
										return value;
 | 
				
			||||||
 | 
									case "MygisPoint": return MygisPoint.Parse(string.Concat(value)) as MygisPoint;
 | 
				
			||||||
 | 
									case "MygisLineString": return MygisLineString.Parse(string.Concat(value)) as MygisLineString;
 | 
				
			||||||
 | 
									case "MygisPolygon": return MygisPolygon.Parse(string.Concat(value)) as MygisPolygon;
 | 
				
			||||||
 | 
									case "MygisMultiPoint": return MygisMultiPoint.Parse(string.Concat(value)) as MygisMultiPoint;
 | 
				
			||||||
 | 
									case "MygisMultiLineString": return MygisMultiLineString.Parse(string.Concat(value)) as MygisMultiLineString;
 | 
				
			||||||
 | 
									case "MygisMultiPolygon": return MygisMultiPolygon.Parse(string.Concat(value)) as MygisMultiPolygon;
 | 
				
			||||||
 | 
									case "Newtonsoft.Json.Linq.JToken": return JToken.Parse(string.Concat(value));
 | 
				
			||||||
 | 
									case "Newtonsoft.Json.Linq.JObject": return JObject.Parse(string.Concat(value));
 | 
				
			||||||
 | 
									case "Newtonsoft.Json.Linq.JArray": return JArray.Parse(string.Concat(value));
 | 
				
			||||||
 | 
									case "Npgsql.LegacyPostgis.PostgisGeometry": return value;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (type != value.GetType()) {
 | 
				
			||||||
 | 
									if (type.FullName == "System.TimeSpan") return TimeSpan.FromSeconds(double.Parse(value.ToString()));
 | 
				
			||||||
 | 
									return Convert.ChangeType(value, type);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return value;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		internal static string GetCsName(string name) {
 | 
							internal static string GetCsName(string name) {
 | 
				
			||||||
			name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
 | 
								name = Regex.Replace(name.TrimStart('@'), @"[^\w]", "_");
 | 
				
			||||||
			return char.IsLetter(name, 0) ? name : string.Concat("_", name);
 | 
								return char.IsLetter(name, 0) ? name : string.Concat("_", name);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,38 +78,38 @@ namespace FreeSql.MySql.Curd {
 | 
				
			|||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); MySqlSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
						class MySqlSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
				
			||||||
		public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
						class MySqlSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
				
			||||||
		public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
						class MySqlSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
				
			||||||
		public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
						class MySqlSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
				
			||||||
		public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
						class MySqlSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
				
			||||||
		public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
						class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
				
			||||||
		public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class {
 | 
						class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class 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 MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 {
 | 
						class MySqlSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public MySqlSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => MySqlSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,38 +89,38 @@ namespace FreeSql.Oracle.Curd {
 | 
				
			|||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); OracleSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); OracleSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); OracleSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); OracleSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); OracleSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); OracleSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
						class OracleSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
				
			||||||
		public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
						class OracleSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
				
			||||||
		public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
						class OracleSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
				
			||||||
		public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
						class OracleSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
				
			||||||
		public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
						class OracleSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
				
			||||||
		public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
						class OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
				
			||||||
		public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class {
 | 
						class OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class 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 OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 {
 | 
						class OracleSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public OracleSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => OracleSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,7 @@ namespace FreeSql.PostgreSQL.Curd {
 | 
				
			|||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); PostgreSQLSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//class PostgreSQLSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T1 : class where T2 : class {
 | 
						//class PostgreSQLSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T1 : class where T2 : class {
 | 
				
			||||||
	//	public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
						//	public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
@@ -88,34 +88,34 @@ namespace FreeSql.PostgreSQL.Curd {
 | 
				
			|||||||
	//}
 | 
						//}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
				
			||||||
		public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
				
			||||||
		public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
				
			||||||
		public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
				
			||||||
		public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
				
			||||||
		public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
				
			||||||
		public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class 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 PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 {
 | 
						class PostgreSQLSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public PostgreSQLSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => PostgreSQLSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,7 +90,7 @@ namespace FreeSql.SqlServer.Curd {
 | 
				
			|||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); SqlServerSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); SqlServerSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); SqlServerSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); SqlServerSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); SqlServerSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); SqlServerSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//class SqlServerSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T1 : class where T2 : class {
 | 
						//class SqlServerSelect<T1, T2> : FreeSql.Internal.CommonProvider.Select2Provider<T1, T2> where T1 : class where T2 : class {
 | 
				
			||||||
	//	public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
						//	public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
@@ -98,34 +98,34 @@ namespace FreeSql.SqlServer.Curd {
 | 
				
			|||||||
	//}
 | 
						//}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
						class SqlServerSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
				
			||||||
		public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
						class SqlServerSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
				
			||||||
		public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
						class SqlServerSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
				
			||||||
		public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
						class SqlServerSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
				
			||||||
		public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
						class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
				
			||||||
		public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
						class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
				
			||||||
		public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class {
 | 
						class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class 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 SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 {
 | 
						class SqlServerSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqlServerSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqlServerSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,38 +78,38 @@ namespace FreeSql.Sqlite.Curd {
 | 
				
			|||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); SqliteSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8> From<T2, T3, T4, T5, T6, T7, T8>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8>(_orm, _commonUtils, _commonExpression, null); SqliteSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); SqliteSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> From<T2, T3, T4, T5, T6, T7, T8, T9>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>(_orm, _commonUtils, _commonExpression, null); SqliteSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); SqliteSelect<T1>.CopyData(this, ret); return ret; }
 | 
							public override ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) { this.InternalFrom(exp?.Body); var ret = new SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); SqliteSelect<T1>.CopyData(this, ret); return ret; }
 | 
				
			||||||
		public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
						class SqliteSelect<T1, T2, T3> : FreeSql.Internal.CommonProvider.Select3Provider<T1, T2, T3> where T1 : class where T2 : class where T3 : class {
 | 
				
			||||||
		public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
						class SqliteSelect<T1, T2, T3, T4> : FreeSql.Internal.CommonProvider.Select4Provider<T1, T2, T3, T4> where T1 : class where T2 : class where T3 : class where T4 : class {
 | 
				
			||||||
		public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
						class SqliteSelect<T1, T2, T3, T4, T5> : FreeSql.Internal.CommonProvider.Select5Provider<T1, T2, T3, T4, T5> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class {
 | 
				
			||||||
		public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
						class SqliteSelect<T1, T2, T3, T4, T5, T6> : FreeSql.Internal.CommonProvider.Select6Provider<T1, T2, T3, T4, T5, T6> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class {
 | 
				
			||||||
		public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
						class SqliteSelect<T1, T2, T3, T4, T5, T6, T7> : FreeSql.Internal.CommonProvider.Select7Provider<T1, T2, T3, T4, T5, T6, T7> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class {
 | 
				
			||||||
		public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
						class SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8> : FreeSql.Internal.CommonProvider.Select8Provider<T1, T2, T3, T4, T5, T6, T7, T8> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class {
 | 
				
			||||||
		public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class {
 | 
						class SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9> : FreeSql.Internal.CommonProvider.Select9Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9> where T1 : class 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 SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	class SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 {
 | 
						class SqliteSelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : FreeSql.Internal.CommonProvider.Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> where T1 : class 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 SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
							public SqliteSelect(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) : base(orm, commonUtils, commonExpression, dywhere) { }
 | 
				
			||||||
		public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllField().field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
							public override string ToSql(string field = null) => SqliteSelect<T1>.ToSqlStatic(_commonUtils, _select, field ?? this.GetAllFieldExpressionTree().Field, _join, _where, _groupby, _having, _orderby, _skip, _limit, _tables, _orm);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								readme.md
									
									
									
									
									
								
							@@ -162,27 +162,31 @@ List<dynamic> t8 = fsql.Ado.Query<dynamic>("select * from song");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### FreeSql Query & Dapper Query
 | 
					### FreeSql Query & Dapper Query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:01.6999868; Query Entity Counts: 131072; ORM: Dapper
 | 
					Elapsed: 00:00:00.6807349; Query Entity Counts: 131072; ORM: Dapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:00.4200430; Query Tuple Counts: 131072; ORM: Dapper
 | 
					Elapsed: 00:00:00.4527258; Query Tuple Counts: 131072; ORM: Dapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:00.6615716; Query Dynamic Counts: 131072; ORM: Dapper
 | 
					Elapsed: 00:00:00.6895447; Query Dynamic Counts: 131072; ORM: Dapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:02.4955996; Query Entity Counts: 131072; ORM: FreeSql*
 | 
					Elapsed: 00:00:00.8253683; Query Entity Counts: 131072; ORM: FreeSql*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:01.2938320; Query Tuple Counts: 131072; ORM: FreeSql*
 | 
					Elapsed: 00:00:00.6503870; Query Tuple Counts: 131072; ORM: FreeSql*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:00.9719682; Query Dynamic Counts: 131072; ORM: FreeSql*
 | 
					Elapsed: 00:00:00.4987399; Query ToList<Tuple> Counts: 131072; ORM: FreeSql*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Elapsed: 00:00:00.9402494; Query Dynamic Counts: 131072; ORM: FreeSql*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### FreeSql ToList & Dapper Query
 | 
					### FreeSql ToList & Dapper Query
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:01.7446031; Query Entity Counts: 131072; ORM: Dapper
 | 
					Elapsed: 00:00:00.7840409; ToList Entity Counts: 131072; ORM: FreeSql*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Elapsed: 00:00:01.2857691; ToList Entity Counts: 131072; ORM: FreeSql*
 | 
					Elapsed: 00:00:00.6414674; Query Entity Counts: 131072; ORM: Dapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[查看测试代码](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs)
 | 
					[查看测试代码](FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FreeSql 目前使用的反射+缓存,硬碰硬比不过 Dapper Emit,真实项目使用相差无几。Emit 在单次查询记录数量越多收益越大。
 | 
					> 以上测试结果运行了两次,为第二次性能报告,避免了首个运行慢不公平的情况
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FreeSql 目前使用的ExpressionTree+缓存,因为支持更为复杂的数据类型,所以比 Dapper Emit 慢少许,真实项目使用其实相差无几。
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Part2 添加
 | 
					# Part2 添加
 | 
				
			||||||
```csharp
 | 
					```csharp
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user