mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 完善 ToChunk 分块加载查询,应用到 ISelect`1..10 中;
This commit is contained in:
		@@ -370,6 +370,12 @@ namespace orm_vs
 | 
				
			|||||||
                testlist2.AddRange(fetch.Object);
 | 
					                testlist2.AddRange(fetch.Object);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var testlist22 = new List<object>();
 | 
				
			||||||
 | 
					            fsql.Select<Song, Song_tag>().LeftJoin((a, b) => a.id == b.song_id).ToChunk((a, b) => new { a.title, a.create_time, b.tag_id }, 2, fetch =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                testlist22.AddRange(fetch.Object);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //sugar.Aop.OnLogExecuted = (s, e) =>
 | 
					            //sugar.Aop.OnLogExecuted = (s, e) =>
 | 
				
			||||||
            //{
 | 
					            //{
 | 
				
			||||||
            //    Trace.WriteLine(s);
 | 
					            //    Trace.WriteLine(s);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -130,13 +130,6 @@
 | 
				
			|||||||
            清空状态数据
 | 
					            清空状态数据
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.DbSet`1.RemoveAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}})">
 | 
					 | 
				
			||||||
            <summary>
 | 
					 | 
				
			||||||
            根据 lambda 条件删除数据
 | 
					 | 
				
			||||||
            </summary>
 | 
					 | 
				
			||||||
            <param name="predicate"></param>
 | 
					 | 
				
			||||||
            <returns></returns>
 | 
					 | 
				
			||||||
        </member>
 | 
					 | 
				
			||||||
        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
					        <member name="M:FreeSql.DbSet`1.Add(`0)">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            添加
 | 
					            添加
 | 
				
			||||||
@@ -421,7 +414,7 @@
 | 
				
			|||||||
            事务传播方式
 | 
					            事务传播方式
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
        <member name="F:FreeSql.Propagation.Requierd">
 | 
					        <member name="F:FreeSql.Propagation.Required">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。
 | 
					            如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
@@ -451,6 +444,11 @@
 | 
				
			|||||||
            以嵌套事务方式执行。
 | 
					            以嵌套事务方式执行。
 | 
				
			||||||
            </summary>
 | 
					            </summary>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="F:FreeSql.Propagation.Requierd">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            错误的命名,请使用 Required,在 2.0.0 删除
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSqlDbContextExtensions.Entity``1(FreeSql.ICodeFirst,System.Action{FreeSql.Extensions.EfCoreFluentApi.EfCoreTableFluent{``0}})">
 | 
					        <member name="M:FreeSqlDbContextExtensions.Entity``1(FreeSql.ICodeFirst,System.Action{FreeSql.Extensions.EfCoreFluentApi.EfCoreTableFluent{``0}})">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            EFCore 95% 相似的 FluentApi 扩展方法
 | 
					            EFCore 95% 相似的 FluentApi 扩展方法
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1645,6 +1645,15 @@
 | 
				
			|||||||
            <typeparam name="TDto"></typeparam>
 | 
					            <typeparam name="TDto"></typeparam>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
 | 
					        <member name="M:FreeSql.ISelect`1.ToChunk``1(System.Linq.Expressions.Expression{System.Func{`0,``0}},System.Int32,System.Action{FreeSql.Internal.Model.FetchCallbackArgs{System.Collections.Generic.List{``0}}})">
 | 
				
			||||||
 | 
					            <summary>
 | 
				
			||||||
 | 
					            执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。
 | 
				
			||||||
 | 
					            </summary>
 | 
				
			||||||
 | 
					            <typeparam name="TReturn">返回类型</typeparam>
 | 
				
			||||||
 | 
					            <param name="select">选择列</param>
 | 
				
			||||||
 | 
					            <param name="size">数据块的大小</param>
 | 
				
			||||||
 | 
					            <param name="done">处理数据块</param>
 | 
				
			||||||
 | 
					        </member>
 | 
				
			||||||
        <member name="M:FreeSql.ISelect`1.ToOne``1(System.Linq.Expressions.Expression{System.Func{`0,``0}})">
 | 
					        <member name="M:FreeSql.ISelect`1.ToOne``1(System.Linq.Expressions.Expression{System.Func{`0,``0}})">
 | 
				
			||||||
            <summary>
 | 
					            <summary>
 | 
				
			||||||
            执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值
 | 
					            执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
using System;
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Data;
 | 
					using System.Data;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -56,6 +57,14 @@ namespace FreeSql
 | 
				
			|||||||
        /// <typeparam name="TDto"></typeparam>
 | 
					        /// <typeparam name="TDto"></typeparam>
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 执行SQL查询,分块返回数据,可减少内存开销。比如读取10万条数据,每次返回100条处理。
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <typeparam name="TReturn">返回类型</typeparam>
 | 
				
			||||||
 | 
					        /// <param name="select">选择列</param>
 | 
				
			||||||
 | 
					        /// <param name="size">数据块的大小</param>
 | 
				
			||||||
 | 
					        /// <param name="done">处理数据块</param>
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值
 | 
					        /// 执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, TReturn>> select); 
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, TReturn>> select); 
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace FreeSql
 | 
				
			|||||||
        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
					        DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
				
			||||||
        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
					        List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
				
			||||||
        List<TDto> ToList<TDto>();
 | 
					        List<TDto> ToList<TDto>();
 | 
				
			||||||
 | 
					        void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
					        TReturn ToOne<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
				
			||||||
        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
					        TReturn First<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,962 @@
 | 
				
			|||||||
 | 
					using FreeSql.Internal.Model;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 | 
					using System.Data;
 | 
				
			||||||
 | 
					using System.Data.Common;
 | 
				
			||||||
 | 
					using System.Diagnostics;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					using System.Threading;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace FreeSql.Internal.CommonProvider
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    partial class Select0Provider<TSelect, T1>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public DataTable ToDataTable(string field = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql = this.ToSql(field);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            DataTable ret = null;
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public List<TTuple> ToList<TTuple>(string field)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql = this.ToSql(field);
 | 
				
			||||||
 | 
					            var type = typeof(TTuple);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new List<TTuple>();
 | 
				
			||||||
 | 
					            var flagStr = $"ToListField:{field}";
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _orm.Ado.ExecuteReader(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils);
 | 
				
			||||||
 | 
					                    ret.Add((TTuple)read.Value);
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal List<T1> ToListAfPrivate(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new List<T1>();
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _orm.Ado.ExecuteReader(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret.Add(af.Read(_orm, fetch.Object));
 | 
				
			||||||
 | 
					                    if (otherData != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var idx = af.FieldCount - 1;
 | 
				
			||||||
 | 
					                        foreach (var other in otherData)
 | 
				
			||||||
 | 
					                            other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            foreach (var include in _includeToList) include?.Invoke(ret);
 | 
				
			||||||
 | 
					            _trackToList?.Invoke(ret);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal List<T1> ToListPrivate(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string sql = null;
 | 
				
			||||||
 | 
					            if (otherData?.Length > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var sbField = new StringBuilder().Append(af.Field);
 | 
				
			||||||
 | 
					                foreach (var other in otherData)
 | 
				
			||||||
 | 
					                    sbField.Append(other.field);
 | 
				
			||||||
 | 
					                sql = this.ToSql(sbField.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ToListAfPrivate(sql, af, otherData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        #region ToChunk
 | 
				
			||||||
 | 
					        internal void ToListAfChunkPrivate(int chunkSize, Action<FetchCallbackArgs<List<T1>>> chunkDone, string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new FetchCallbackArgs<List<T1>> { Object = new List<T1>() };
 | 
				
			||||||
 | 
					            var retCount = 0;
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            var checkDoneTimes = 0;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _orm.Ado.ExecuteReader(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret.Object.Add(af.Read(_orm, fetch.Object));
 | 
				
			||||||
 | 
					                    retCount++;
 | 
				
			||||||
 | 
					                    if (otherData != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var idx = af.FieldCount - 1;
 | 
				
			||||||
 | 
					                        foreach (var other in otherData)
 | 
				
			||||||
 | 
					                            other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (chunkSize > 0 && chunkSize == ret.Object.Count)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        checkDoneTimes++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        foreach (var include in _includeToList) include?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                        _trackToList?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                        chunkDone(ret);
 | 
				
			||||||
 | 
					                        fetch.IsBreak = ret.IsBreak;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        ret.Object.Clear();
 | 
				
			||||||
 | 
					                        if (otherData != null)
 | 
				
			||||||
 | 
					                            foreach (var other in otherData)
 | 
				
			||||||
 | 
					                                other.retlist.Clear();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, retCount);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (ret.Object.Any() || checkDoneTimes == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (var include in _includeToList) include?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                _trackToList?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                chunkDone(ret);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal void ToListChunkPrivate(int chunkSize, Action<FetchCallbackArgs<List<T1>>> chunkDone, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string sql = null;
 | 
				
			||||||
 | 
					            if (otherData?.Length > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var sbField = new StringBuilder().Append(af.Field);
 | 
				
			||||||
 | 
					                foreach (var other in otherData)
 | 
				
			||||||
 | 
					                    sbField.Append(other.field);
 | 
				
			||||||
 | 
					                sql = this.ToSql(sbField.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ToListAfChunkPrivate(chunkSize, chunkDone, sql, af, otherData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk(int size, Action<FetchCallbackArgs<List<T1>>> done, bool includeNestedMembers = false)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (_selectExpression != null) throw new ArgumentException("Chunk 功能之前不可使用 Select");
 | 
				
			||||||
 | 
					            this.ToListChunkPrivate(size, done, includeNestedMembers == false ? this.GetAllFieldExpressionTreeLevel2() : this.GetAllFieldExpressionTreeLevelAll(), null);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal void ToListMrChunkPrivate<TReturn>(int chunkSize, Action<FetchCallbackArgs<List<TReturn>>> chunkDone, string sql, ReadAnonymousTypeAfInfo af)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var type = typeof(TReturn);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new FetchCallbackArgs<List<TReturn>> { Object = new List<TReturn>() };
 | 
				
			||||||
 | 
					            var retCount = 0;
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            var checkDoneTimes = 0;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _orm.Ado.ExecuteReader(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var index = -1;
 | 
				
			||||||
 | 
					                    ret.Object.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null));
 | 
				
			||||||
 | 
					                    retCount++;
 | 
				
			||||||
 | 
					                    if (chunkSize > 0 && chunkSize == ret.Object.Count)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        checkDoneTimes++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        foreach (var include in _includeToList) include?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                        _trackToList?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                        chunkDone(ret);
 | 
				
			||||||
 | 
					                        fetch.IsBreak = ret.IsBreak;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        ret.Object.Clear();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, retCount);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (ret.Object.Any() || checkDoneTimes == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (var include in _includeToList) include?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                _trackToList?.Invoke(ret.Object);
 | 
				
			||||||
 | 
					                chunkDone(ret);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public void InternalToChunk<TReturn>(Expression select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var af = this.GetExpressionField(select);
 | 
				
			||||||
 | 
					            var sql = this.ToSql(af.field);
 | 
				
			||||||
 | 
					            this.ToListMrChunkPrivate<TReturn>(size, done, sql, af);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Dictionary<TKey, T1> ToDictionary<TKey>(Func<T1, TKey> keySelector) => ToDictionary(keySelector, a => a);
 | 
				
			||||||
 | 
					        public Dictionary<TKey, TElement> ToDictionary<TKey, TElement>(Func<T1, TKey> keySelector, Func<T1, TElement> elementSelector)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
 | 
				
			||||||
 | 
					            if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector));
 | 
				
			||||||
 | 
					            var af = this.GetAllFieldExpressionTreeLevel2();
 | 
				
			||||||
 | 
					            var sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new Dictionary<TKey, TElement>();
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _orm.Ado.ExecuteReader(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var item = af.Read(_orm, fetch.Object);
 | 
				
			||||||
 | 
					                    ret.Add(keySelector(item), elementSelector(item));
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal List<TReturn> ToListMrPrivate<TReturn>(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var type = typeof(TReturn);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new List<TReturn>();
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _orm.Ado.ExecuteReader(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var index = -1;
 | 
				
			||||||
 | 
					                    ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null));
 | 
				
			||||||
 | 
					                    if (otherData != null)
 | 
				
			||||||
 | 
					                        foreach (var other in otherData)
 | 
				
			||||||
 | 
					                            other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null));
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (typeof(TReturn) == typeof(T1))
 | 
				
			||||||
 | 
					                foreach (var include in _includeToList) include?.Invoke(ret);
 | 
				
			||||||
 | 
					            _trackToList?.Invoke(ret);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal List<TReturn> ToListMapReaderPrivate<TReturn>(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string sql = null;
 | 
				
			||||||
 | 
					            if (otherData?.Length > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var sbField = new StringBuilder().Append(af.field);
 | 
				
			||||||
 | 
					                foreach (var other in otherData)
 | 
				
			||||||
 | 
					                    sbField.Append(other.field);
 | 
				
			||||||
 | 
					                sql = this.ToSql(sbField.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                sql = this.ToSql(af.field);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ToListMrPrivate<TReturn>(sql, af, otherData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        protected List<TReturn> ToListMapReader<TReturn>(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivate<TReturn>(af, null);
 | 
				
			||||||
 | 
					        protected ReadAnonymousTypeAfInfo GetExpressionField(Expression newexp, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
 | 
					            var field = new StringBuilder();
 | 
				
			||||||
 | 
					            var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null, _whereCascadeExpression, true);
 | 
				
			||||||
 | 
					            return new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        static ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo> _dicGetAllFieldExpressionTree = new ConcurrentDictionary<string, GetAllFieldExpressionTreeInfo>();
 | 
				
			||||||
 | 
					        public class GetAllFieldExpressionTreeInfo
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string Field { get; set; }
 | 
				
			||||||
 | 
					            public int FieldCount { get; set; }
 | 
				
			||||||
 | 
					            public Func<IFreeSql, DbDataReader, T1> Read { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevelAll()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _dicGetAllFieldExpressionTree.GetOrAdd($"*{string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}"))}", s =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var type = _tables.First().Table.TypeLazy ?? _tables.First().Table.Type;
 | 
				
			||||||
 | 
					                var ormExp = Expression.Parameter(typeof(IFreeSql), "orm");
 | 
				
			||||||
 | 
					                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>();
 | 
				
			||||||
 | 
					                blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                    Expression.Assign(retExp, type.InternalNewExpression()),
 | 
				
			||||||
 | 
					                    Expression.Assign(dataIndexExp, Expression.Constant(0))
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                //typeof(Topic).GetMethod("get_Type").IsVirtual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var field = new StringBuilder();
 | 
				
			||||||
 | 
					                var dicfield = new Dictionary<string, bool>();
 | 
				
			||||||
 | 
					                var tb = _tables.First();
 | 
				
			||||||
 | 
					                var index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var tborder = new[] { tb }.Concat(_tables.ToArray().Where((a, b) => b > 0).OrderBy(a => a.Alias));
 | 
				
			||||||
 | 
					                var tbiindex = 0;
 | 
				
			||||||
 | 
					                foreach (var tbi in tborder)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (tbiindex > 0 && tbi.Type == SelectTableInfoType.From) continue;
 | 
				
			||||||
 | 
					                    if (tbiindex > 0 && tbi.Alias.StartsWith($"{tb.Alias}__") == false) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    var typei = tbi.Table.TypeLazy ?? tbi.Table.Type;
 | 
				
			||||||
 | 
					                    Expression curExp = retExp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    var colidx = 0;
 | 
				
			||||||
 | 
					                    foreach (var col in tbi.Table.Columns.Values)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        if (index > 0)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            field.Append(", ");
 | 
				
			||||||
 | 
					                            if (tbiindex > 0 && colidx == 0) field.Append("\r\n");
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        var quoteName = _commonUtils.QuoteSqlName(col.Attribute.Name);
 | 
				
			||||||
 | 
					                        field.Append(_commonUtils.QuoteReadColumn(col.CsType, col.Attribute.MapType, $"{tbi.Alias}.{quoteName}"));
 | 
				
			||||||
 | 
					                        ++index;
 | 
				
			||||||
 | 
					                        if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}"));
 | 
				
			||||||
 | 
					                        else dicfield.Add(quoteName, true);
 | 
				
			||||||
 | 
					                        ++colidx;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    tbiindex++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (tbiindex == 0)
 | 
				
			||||||
 | 
					                        blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                            Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
 | 
				
			||||||
 | 
					                            Expression.IfThen(
 | 
				
			||||||
 | 
					                                Expression.GreaterThan(readExpDataIndex, dataIndexExp),
 | 
				
			||||||
 | 
					                                Expression.Assign(dataIndexExp, readExpDataIndex)
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                            Expression.IfThen(
 | 
				
			||||||
 | 
					                                Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                                Expression.Assign(retExp, Expression.Convert(readExpValue, typei))
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Expression curExpIfNotNull = Expression.IsTrue(Expression.Constant(true));
 | 
				
			||||||
 | 
					                        var curTb = tb;
 | 
				
			||||||
 | 
					                        var parentNameSplits = tbi.Alias.Split(new[] { "__" }, StringSplitOptions.None);
 | 
				
			||||||
 | 
					                        var iscontinue = false;
 | 
				
			||||||
 | 
					                        for (var k = 1; k < parentNameSplits.Length; k++)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var curPropName = parentNameSplits[k];
 | 
				
			||||||
 | 
					                            if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out var tryprop) == false)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                k++;
 | 
				
			||||||
 | 
					                                curPropName = $"{curPropName}__{parentNameSplits[k]}";
 | 
				
			||||||
 | 
					                                if (curTb.Table.Properties.TryGetValue(parentNameSplits[k], out tryprop) == false)
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    iscontinue = true;
 | 
				
			||||||
 | 
					                                    break;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            curExp = Expression.MakeMemberAccess(curExp, tryprop);
 | 
				
			||||||
 | 
					                            if (k + 1 < parentNameSplits.Length)
 | 
				
			||||||
 | 
					                                curExpIfNotNull = Expression.AndAlso(curExpIfNotNull, Expression.NotEqual(curExp, Expression.Default(tryprop.PropertyType)));
 | 
				
			||||||
 | 
					                            curTb = _tables.Where(a => a.Alias == $"{curTb.Alias}__{curPropName}" && a.Table.Type == tryprop.PropertyType).FirstOrDefault();
 | 
				
			||||||
 | 
					                            if (curTb == null)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                iscontinue = true;
 | 
				
			||||||
 | 
					                                break;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        if (iscontinue) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        blockExp.Add(
 | 
				
			||||||
 | 
					                            Expression.IfThenElse(
 | 
				
			||||||
 | 
					                                curExpIfNotNull,
 | 
				
			||||||
 | 
					                                Expression.Block(new Expression[] {
 | 
				
			||||||
 | 
					                                    Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(typei), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
 | 
				
			||||||
 | 
					                                    Expression.IfThen(
 | 
				
			||||||
 | 
					                                        Expression.GreaterThan(readExpDataIndex, dataIndexExp),
 | 
				
			||||||
 | 
					                                        Expression.Assign(dataIndexExp, readExpDataIndex)
 | 
				
			||||||
 | 
					                                    ),
 | 
				
			||||||
 | 
					                                    Expression.IfThenElse(
 | 
				
			||||||
 | 
					                                        Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                                        Expression.Assign(curExp, Expression.Convert(readExpValue, typei)),
 | 
				
			||||||
 | 
					                                        Expression.Assign(curExp, Expression.Constant(null, typei))
 | 
				
			||||||
 | 
					                                    )
 | 
				
			||||||
 | 
					                                }),
 | 
				
			||||||
 | 
					                                Expression.Block(
 | 
				
			||||||
 | 
					                                    Expression.Assign(readExpValue, Expression.Constant(null, typeof(object))),
 | 
				
			||||||
 | 
					                                    Expression.Assign(dataIndexExp, Expression.Constant(index))
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (tbi.Table.TypeLazy != null)
 | 
				
			||||||
 | 
					                        blockExp.Add(
 | 
				
			||||||
 | 
					                            Expression.IfThen(
 | 
				
			||||||
 | 
					                                Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                                Expression.Call(Expression.TypeAs(readExpValue, typei), tbi.Table.TypeLazySetOrm, ormExp)
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        ); //将 orm 传递给 lazy
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                    Expression.Return(returnTarget, retExp),
 | 
				
			||||||
 | 
					                    Expression.Label(returnTarget, Expression.Default(type))
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                return new GetAllFieldExpressionTreeInfo
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Field = field.ToString(),
 | 
				
			||||||
 | 
					                    FieldCount = index,
 | 
				
			||||||
 | 
					                    Read = Expression.Lambda<Func<IFreeSql, DbDataReader, T1>>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile()
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GetAllFieldExpressionTreeInfo GetAllFieldExpressionTreeLevel2()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _dicGetAllFieldExpressionTree.GetOrAdd(string.Join("+", _tables.Select(a => $"{_orm.Ado.DataType}-{a.Table.DbName}-{a.Alias}-{a.Type}")), s =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var tb1 = _tables.First().Table;
 | 
				
			||||||
 | 
					                var type = tb1.TypeLazy ?? tb1.Type;
 | 
				
			||||||
 | 
					                var props = tb1.Properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var ormExp = Expression.Parameter(typeof(IFreeSql), "orm");
 | 
				
			||||||
 | 
					                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>();
 | 
				
			||||||
 | 
					                blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                    Expression.Assign(retExp, type.InternalNewExpression()),
 | 
				
			||||||
 | 
					                    Expression.Assign(dataIndexExp, Expression.Constant(0))
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                //typeof(Topic).GetMethod("get_Type").IsVirtual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var field = new StringBuilder();
 | 
				
			||||||
 | 
					                var dicfield = new Dictionary<string, bool>();
 | 
				
			||||||
 | 
					                var tb = _tables.First();
 | 
				
			||||||
 | 
					                var index = 0;
 | 
				
			||||||
 | 
					                var otherindex = 0;
 | 
				
			||||||
 | 
					                foreach (var prop in props.Values)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (tb.Table.ColumnsByCsIgnore.ContainsKey(prop.Name)) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    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, col.Attribute.MapType, $"{tb.Alias}.{quoteName}"));
 | 
				
			||||||
 | 
					                        ++index;
 | 
				
			||||||
 | 
					                        if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}"));
 | 
				
			||||||
 | 
					                        else dicfield.Add(quoteName, true);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var tb2 = _tables.Where((a, b) => b > 0 &&
 | 
				
			||||||
 | 
					                            (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) &&
 | 
				
			||||||
 | 
					                            string.IsNullOrEmpty(a.On) == false &&
 | 
				
			||||||
 | 
					                            a.Alias.StartsWith($"{tb.Alias}__") && //开头结尾完全匹配
 | 
				
			||||||
 | 
					                            a.Alias.EndsWith($"__{prop.Name}") //不清楚会不会有其他情况 求大佬优化
 | 
				
			||||||
 | 
					                            ).FirstOrDefault(); //判断 b > 0 防止 parent 递归关系
 | 
				
			||||||
 | 
					                        if (tb2 == null && props.Where(pw => pw.Value.PropertyType == prop.PropertyType).Count() == 1)
 | 
				
			||||||
 | 
					                            tb2 = _tables.Where((a, b) => b > 0 &&
 | 
				
			||||||
 | 
					                                (a.Type == SelectTableInfoType.InnerJoin || a.Type == SelectTableInfoType.LeftJoin || a.Type == SelectTableInfoType.RightJoin) &&
 | 
				
			||||||
 | 
					                                string.IsNullOrEmpty(a.On) == false &&
 | 
				
			||||||
 | 
					                                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, col2.Attribute.MapType, $"{tb2.Alias}.{quoteName}"));
 | 
				
			||||||
 | 
					                            ++index;
 | 
				
			||||||
 | 
					                            ++otherindex;
 | 
				
			||||||
 | 
					                            if (dicfield.ContainsKey(quoteName)) field.Append(_commonUtils.FieldAsAlias($"as{index}"));
 | 
				
			||||||
 | 
					                            else dicfield.Add(quoteName, true);
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    //只读到二级属性
 | 
				
			||||||
 | 
					                    var propGetSetMethod = prop.GetSetMethod(true);
 | 
				
			||||||
 | 
					                    Expression readExpAssign = null; //加速缓存
 | 
				
			||||||
 | 
					                    if (prop.PropertyType.IsArray) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
 | 
				
			||||||
 | 
					                        Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })),
 | 
				
			||||||
 | 
					                        //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.IsNullableType()) proptypeGeneric = proptypeGeneric.GetGenericArguments().First();
 | 
				
			||||||
 | 
					                        if (proptypeGeneric.IsEnum ||
 | 
				
			||||||
 | 
					                            Utils.dicExecuteArrayRowReadClassOrTuple.ContainsKey(proptypeGeneric)) readExpAssign = Expression.New(Utils.RowInfo.Constructor,
 | 
				
			||||||
 | 
					                                Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Call(Utils.MethodDataReaderGetValue, new Expression[] { Expression.Constant(_commonUtils), rowExp, dataIndexExp })),
 | 
				
			||||||
 | 
					                                //Expression.Call(Utils.MethodGetDataReaderValue, new Expression[] { Expression.Constant(prop.PropertyType), Expression.Call(rowExp, Utils.MethodDataReaderGetValue, dataIndexExp) }),
 | 
				
			||||||
 | 
					                                Expression.Add(dataIndexExp, Expression.Constant(1))
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                        else
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            var propLazyType = _commonUtils.GetTableByEntity(prop.PropertyType)?.TypeLazy ?? prop.PropertyType;
 | 
				
			||||||
 | 
					                            readExpAssign = Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(propLazyType), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) });
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                        Expression.Assign(readExp, readExpAssign),
 | 
				
			||||||
 | 
					                        Expression.IfThen(Expression.GreaterThan(readExpDataIndex, dataIndexExp),
 | 
				
			||||||
 | 
					                            Expression.Assign(dataIndexExp, readExpDataIndex)),
 | 
				
			||||||
 | 
											//Expression.Call(typeof(Trace).GetMethod("WriteLine", new Type[]{typeof(string)}), Expression.Call(typeof(string).GetMethod("Concat", new Type[]{typeof(object) }), readExpValue)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											tb1.TypeLazy != null ?
 | 
				
			||||||
 | 
					                            Expression.IfThenElse(
 | 
				
			||||||
 | 
					                                Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                                Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType)),
 | 
				
			||||||
 | 
					                                Expression.Call(retExp, propGetSetMethod, Expression.Convert(Utils.GetDataReaderValueBlockExpression(prop.PropertyType, Expression.Constant(null)), prop.PropertyType))
 | 
				
			||||||
 | 
					                            ) :
 | 
				
			||||||
 | 
					                            Expression.IfThen(
 | 
				
			||||||
 | 
					                                Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                                Expression.Call(retExp, propGetSetMethod, Expression.Convert(readExpValue, prop.PropertyType))
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (otherindex == 0)
 | 
				
			||||||
 | 
					                { //不读导航属性,优化单表读取性能
 | 
				
			||||||
 | 
					                    blockExp.Clear();
 | 
				
			||||||
 | 
					                    blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                        Expression.Assign(dataIndexExp, Expression.Constant(0)),
 | 
				
			||||||
 | 
					                        Expression.Assign(readExp, Expression.Call(Utils.MethodExecuteArrayRowReadClassOrTuple, new Expression[] { Expression.Constant(null, typeof(string)), Expression.Constant(type), Expression.Constant(null, typeof(int[])), rowExp, dataIndexExp, Expression.Constant(_commonUtils) })),
 | 
				
			||||||
 | 
					                        Expression.IfThen(
 | 
				
			||||||
 | 
					                            Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                            Expression.Assign(retExp, Expression.Convert(readExpValue, type))
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (tb1.TypeLazy != null)
 | 
				
			||||||
 | 
					                    blockExp.Add(
 | 
				
			||||||
 | 
					                        Expression.IfThen(
 | 
				
			||||||
 | 
					                            Expression.NotEqual(readExpValue, Expression.Constant(null)),
 | 
				
			||||||
 | 
					                            Expression.Call(retExp, tb1.TypeLazySetOrm, ormExp)
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    ); //将 orm 传递给 lazy
 | 
				
			||||||
 | 
					                blockExp.AddRange(new Expression[] {
 | 
				
			||||||
 | 
					                    Expression.Return(returnTarget, retExp),
 | 
				
			||||||
 | 
					                    Expression.Label(returnTarget, Expression.Default(type))
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                return new GetAllFieldExpressionTreeInfo
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Field = field.ToString(),
 | 
				
			||||||
 | 
					                    Read = Expression.Lambda<Func<IFreeSql, DbDataReader, T1>>(Expression.Block(new[] { retExp, dataIndexExp, readExp }, blockExp), new[] { ormExp, rowExp }).Compile()
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected double InternalAvg(Expression exp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var list = this.ToList<double>($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}");
 | 
				
			||||||
 | 
					            return list.Sum() / list.Count;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        protected TMember InternalMax<TMember>(Expression exp) => this.ToList<TMember>($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Max();
 | 
				
			||||||
 | 
					        protected TMember InternalMin<TMember>(Expression exp) => this.ToList<TMember>($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Min();
 | 
				
			||||||
 | 
					        protected decimal InternalSum(Expression exp) => this.ToList<decimal>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}").Sum();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public ISelectGrouping<TKey, TValue> InternalGroupBy<TKey, TValue>(Expression columns)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
 | 
					            var field = new StringBuilder();
 | 
				
			||||||
 | 
					            var index = -10000; //临时规则,不返回 as1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null, _whereCascadeExpression, false); //不走 DTO 映射
 | 
				
			||||||
 | 
					            var sql = field.ToString();
 | 
				
			||||||
 | 
					            this.GroupBy(sql.Length > 0 ? sql.Substring(2) : null);
 | 
				
			||||||
 | 
					            return new SelectGroupingProvider<TKey, TValue>(_orm, this, map, sql, _commonExpression, _tables);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public TSelect InternalJoin(Expression exp, SelectTableInfoType joinType)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression);
 | 
				
			||||||
 | 
					            return this as TSelect;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        protected TSelect InternalJoin<T2>(Expression exp, SelectTableInfoType joinType)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var tb = _commonUtils.GetTableByEntity(typeof(T2));
 | 
				
			||||||
 | 
					            if (tb == null) throw new ArgumentException("T2 类型错误");
 | 
				
			||||||
 | 
					            _tables.Add(new SelectTableInfo { Table = tb, Alias = $"IJ{_tables.Count}", On = null, Type = joinType });
 | 
				
			||||||
 | 
					            _commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null, _whereCascadeExpression);
 | 
				
			||||||
 | 
					            return this as TSelect;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null));
 | 
				
			||||||
 | 
					        protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public List<TReturn> InternalToList<TReturn>(Expression select) => this.ToListMapReader<TReturn>(this.GetExpressionField(select));
 | 
				
			||||||
 | 
					        protected string InternalToSql<TReturn>(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var af = this.GetExpressionField(select, fieldAlias);
 | 
				
			||||||
 | 
					            return this.ToSql(af.field);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected DataTable InternalToDataTable(Expression select)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql = this.InternalToSql<int>(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            DataTable ret = null;
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = _orm.Ado.ExecuteDataTable(_connection, _transaction, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected TReturn InternalToAggregate<TReturn>(Expression select)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
 | 
					            var field = new StringBuilder();
 | 
				
			||||||
 | 
					            var index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射
 | 
				
			||||||
 | 
					            return this.ToListMapReader<TReturn>(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public TSelect InternalWhere(Expression exp) => exp == null ? this as TSelect : this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null, _whereCascadeExpression, _params));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Async
 | 
				
			||||||
 | 
					#if net40
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					        async public Task<DataTable> ToDataTableAsync(string field = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql = this.ToSql(field);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            DataTable ret = null;
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async public Task<List<TTuple>> ToListAsync<TTuple>(string field)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql = this.ToSql(field);
 | 
				
			||||||
 | 
					            var type = typeof(TTuple);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new List<TTuple>();
 | 
				
			||||||
 | 
					            var flagStr = $"ToListField:{field}";
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var read = Utils.ExecuteArrayRowReadClassOrTuple(flagStr, type, null, fetch.Object, 0, _commonUtils);
 | 
				
			||||||
 | 
					                    ret.Add((TTuple)read.Value);
 | 
				
			||||||
 | 
					                    return Task.FromResult(false);
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async internal Task<List<T1>> ToListAfPrivateAsync(string sql, GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new List<T1>();
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ret.Add(af.Read(_orm, fetch.Object));
 | 
				
			||||||
 | 
					                    if (otherData != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var idx = af.FieldCount - 1;
 | 
				
			||||||
 | 
					                        foreach (var other in otherData)
 | 
				
			||||||
 | 
					                            other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref idx, false, null));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return Task.FromResult(false);
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            foreach (var include in _includeToListAsync) await include?.Invoke(ret);
 | 
				
			||||||
 | 
					            _trackToList?.Invoke(ret);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        internal Task<List<T1>> ToListPrivateAsync(GetAllFieldExpressionTreeInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string sql = null;
 | 
				
			||||||
 | 
					            if (otherData?.Length > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var sbField = new StringBuilder().Append(af.Field);
 | 
				
			||||||
 | 
					                foreach (var other in otherData)
 | 
				
			||||||
 | 
					                    sbField.Append(other.field);
 | 
				
			||||||
 | 
					                sql = this.ToSql(sbField.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ToListAfPrivateAsync(sql, af, otherData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Task<Dictionary<TKey, T1>> ToDictionaryAsync<TKey>(Func<T1, TKey> keySelector) => ToDictionaryAsync(keySelector, a => a);
 | 
				
			||||||
 | 
					        async public Task<Dictionary<TKey, TElement>> ToDictionaryAsync<TKey, TElement>(Func<T1, TKey> keySelector, Func<T1, TElement> elementSelector)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
 | 
				
			||||||
 | 
					            if (elementSelector == null) throw new ArgumentNullException(nameof(elementSelector));
 | 
				
			||||||
 | 
					            var af = this.GetAllFieldExpressionTreeLevel2();
 | 
				
			||||||
 | 
					            var sql = this.ToSql(af.Field);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new Dictionary<TKey, TElement>();
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var item = af.Read(_orm, fetch.Object);
 | 
				
			||||||
 | 
					                    ret.Add(keySelector(item), elementSelector(item));
 | 
				
			||||||
 | 
					                    return Task.FromResult(false);
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (typeof(TElement) == typeof(T1)) _trackToList?.Invoke(ret.Values);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async internal Task<List<TReturn>> ToListMrPrivateAsync<TReturn>(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var type = typeof(TReturn);
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            var ret = new List<TReturn>();
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch =>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var index = -1;
 | 
				
			||||||
 | 
					                    ret.Add((TReturn)_commonExpression.ReadAnonymous(af.map, fetch.Object, ref index, false, null));
 | 
				
			||||||
 | 
					                    if (otherData != null)
 | 
				
			||||||
 | 
					                        foreach (var other in otherData)
 | 
				
			||||||
 | 
					                            other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null));
 | 
				
			||||||
 | 
					                    return Task.FromResult(false);
 | 
				
			||||||
 | 
					                }, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (typeof(TReturn) == typeof(T1))
 | 
				
			||||||
 | 
					                foreach (var include in _includeToListAsync) await include?.Invoke(ret);
 | 
				
			||||||
 | 
					            _trackToList?.Invoke(ret);
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        internal Task<List<TReturn>> ToListMapReaderPrivateAsync<TReturn>(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string sql = null;
 | 
				
			||||||
 | 
					            if (otherData?.Length > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var sbField = new StringBuilder().Append(af.field);
 | 
				
			||||||
 | 
					                foreach (var other in otherData)
 | 
				
			||||||
 | 
					                    sbField.Append(other.field);
 | 
				
			||||||
 | 
					                sql = this.ToSql(sbField.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                sql = this.ToSql(af.field);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ToListMrPrivateAsync<TReturn>(sql, af, otherData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        protected Task<List<TReturn>> ToListMapReaderAsync<TReturn>(ReadAnonymousTypeAfInfo af) => ToListMapReaderPrivateAsync<TReturn>(af, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async protected Task<double> InternalAvgAsync(Expression exp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var list = await this.ToListAsync<double>($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}");
 | 
				
			||||||
 | 
					            return list.Sum() / list.Count;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        async protected Task<TMember> InternalMaxAsync<TMember>(Expression exp) => (await this.ToListAsync<TMember>($"max({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Max();
 | 
				
			||||||
 | 
					        async protected Task<TMember> InternalMinAsync<TMember>(Expression exp) => (await this.ToListAsync<TMember>($"min({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Min();
 | 
				
			||||||
 | 
					        async protected Task<decimal> InternalSumAsync(Expression exp) => (await this.ToListAsync<decimal>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)}){_commonUtils.FieldAsAlias("as1")}")).Sum();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected Task<List<TReturn>> InternalToListAsync<TReturn>(Expression select) => this.ToListMapReaderAsync<TReturn>(this.GetExpressionField(select));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async protected Task<DataTable> InternalToDataTableAsync(Expression select)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql = this.InternalToSql<int>(select, FieldAliasOptions.AsProperty); //DataTable 使用 AsProperty
 | 
				
			||||||
 | 
					            var dbParms = _params.ToArray();
 | 
				
			||||||
 | 
					            var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms);
 | 
				
			||||||
 | 
					            _orm.Aop.CurdBeforeHandler?.Invoke(this, before);
 | 
				
			||||||
 | 
					            DataTable ret = null;
 | 
				
			||||||
 | 
					            Exception exception = null;
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ret = await _orm.Ado.ExecuteDataTableAsync(_connection, _transaction, CommandType.Text, sql, dbParms);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                exception = ex;
 | 
				
			||||||
 | 
					                throw ex;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var after = new Aop.CurdAfterEventArgs(before, exception, ret);
 | 
				
			||||||
 | 
					                _orm.Aop.CurdAfterHandler?.Invoke(this, after);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async protected Task<TReturn> InternalToAggregateAsync<TReturn>(Expression select)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var map = new ReadAnonymousTypeInfo();
 | 
				
			||||||
 | 
					            var field = new StringBuilder();
 | 
				
			||||||
 | 
					            var index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null, _whereCascadeExpression, false); //不走 DTO 映射
 | 
				
			||||||
 | 
					            return (await this.ToListMapReaderAsync<TReturn>(new ReadAnonymousTypeAfInfo(map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -134,6 +134,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T9), "i"),
 | 
					                Expression.Parameter(typeof(T9), "i"),
 | 
				
			||||||
                Expression.Parameter(typeof(T10), "j"));
 | 
					                Expression.Parameter(typeof(T10), "j"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,7 +174,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            _tables[0].Parameter = select.Parameters[0];
 | 
					            _tables[0].Parameter = select.Parameters[0];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select.Body);
 | 
					            return this.InternalToList<TReturn>(select.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public List<TDto> ToList<TDto>() => ToList(GetToListDtoSelector<TDto>());
 | 
					        public List<TDto> ToList<TDto>() => ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -182,6 +181,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                typeof(TDto).InternalNewExpression(),
 | 
					                typeof(TDto).InternalNewExpression(),
 | 
				
			||||||
                _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"));
 | 
					                _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            _tables[0].Parameter = select.Parameters[0];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DataTable ToDataTable<TReturn>(Expression<Func<T1, TReturn>> select)
 | 
					        public DataTable ToDataTable<TReturn>(Expression<Func<T1, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,7 +94,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2>.ToList<TDto>() => (this as ISelect<T1, T2>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2>.ToList<TDto>() => (this as ISelect<T1, T2>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, T2, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -103,6 +102,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
 | 
					                _tables[0].Parameter ?? Expression.Parameter(typeof(T1), "a"),
 | 
				
			||||||
                Expression.Parameter(typeof(T2), "b"));
 | 
					                Expression.Parameter(typeof(T2), "b"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2>.ToDataTable<TReturn>(Expression<Func<T1, T2, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2>.ToDataTable<TReturn>(Expression<Func<T1, T2, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,7 +97,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2, T3>.ToList<TDto>() => (this as ISelect<T1, T2, T3>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2, T3>.ToList<TDto>() => (this as ISelect<T1, T2, T3>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, T2, T3, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, T3, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -107,6 +106,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T2), "b"),
 | 
					                Expression.Parameter(typeof(T2), "b"),
 | 
				
			||||||
                Expression.Parameter(typeof(T3), "c"));
 | 
					                Expression.Parameter(typeof(T3), "c"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,7 +100,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2, T3, T4>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2, T3, T4>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, T2, T3, T4, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, T3, T4, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -111,6 +110,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T3), "c"),
 | 
					                Expression.Parameter(typeof(T3), "c"),
 | 
				
			||||||
                Expression.Parameter(typeof(T4), "d"));
 | 
					                Expression.Parameter(typeof(T4), "d"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,7 +103,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2, T3, T4, T5>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2, T3, T4, T5>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, T2, T3, T4, T5, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, T3, T4, T5, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -115,6 +114,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T4), "d"),
 | 
					                Expression.Parameter(typeof(T4), "d"),
 | 
				
			||||||
                Expression.Parameter(typeof(T5), "e"));
 | 
					                Expression.Parameter(typeof(T5), "e"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4, T5>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4, T5>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,7 +106,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2, T3, T4, T5, T6>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2, T3, T4, T5, T6>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, T2, T3, T4, T5, T6, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, T3, T4, T5, T6, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -119,6 +118,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T5), "e"),
 | 
					                Expression.Parameter(typeof(T5), "e"),
 | 
				
			||||||
                Expression.Parameter(typeof(T6), "f"));
 | 
					                Expression.Parameter(typeof(T6), "f"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4, T5, T6>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4, T5, T6>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -109,7 +109,6 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
        Expression<Func<T1, T2, T3, T4, T5, T6, T7, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, T3, T4, T5, T6, T7, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -123,6 +122,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T6), "f"),
 | 
					                Expression.Parameter(typeof(T6), "f"),
 | 
				
			||||||
                Expression.Parameter(typeof(T7), "g"));
 | 
					                Expression.Parameter(typeof(T7), "g"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -112,9 +112,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
            return this.InternalToList<TReturn>(select?.Body);
 | 
					            return this.InternalToList<TReturn>(select?.Body);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7, T8>).ToList(GetToListDtoSelector<TDto>());
 | 
					        List<TDto> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.ToList<TDto>() => (this as ISelect<T1, T2, T3, T4, T5, T6, T7, T8>).ToList(GetToListDtoSelector<TDto>());
 | 
				
			||||||
 | 
					 | 
				
			||||||
        Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>> GetToListDtoSelector<TDto>()
 | 
					        Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>> GetToListDtoSelector<TDto>()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>>(
 | 
					            return Expression.Lambda<Func<T1, T2, T3, T4, T5, T6, T7, T8, TDto>>(
 | 
				
			||||||
@@ -128,6 +126,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T7), "g"),
 | 
					                Expression.Parameter(typeof(T7), "g"),
 | 
				
			||||||
                Expression.Parameter(typeof(T8), "h"));
 | 
					                Expression.Parameter(typeof(T8), "h"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -130,6 +130,12 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
                Expression.Parameter(typeof(T8), "h"),
 | 
					                Expression.Parameter(typeof(T8), "h"),
 | 
				
			||||||
                Expression.Parameter(typeof(T9), "i"));
 | 
					                Expression.Parameter(typeof(T9), "i"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        public void ToChunk<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select, int size, Action<FetchCallbackArgs<List<TReturn>>> done)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (select == null || done == null) return;
 | 
				
			||||||
 | 
					            for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
 | 
				
			||||||
 | 
					            this.InternalToChunk<TReturn>(select.Body, size, done);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select)
 | 
					        DataTable ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.ToDataTable<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user