mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 18:52:50 +08:00
- 完善 ToChunk 分块加载查询,应用到 ISelect`1..10 中;
This commit is contained in:
parent
4acbc712d6
commit
7dd8eacce3
@ -370,6 +370,12 @@ namespace orm_vs
|
||||
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) =>
|
||||
//{
|
||||
// Trace.WriteLine(s);
|
||||
|
@ -130,13 +130,6 @@
|
||||
清空状态数据
|
||||
</summary>
|
||||
</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)">
|
||||
<summary>
|
||||
添加
|
||||
@ -421,7 +414,7 @@
|
||||
事务传播方式
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:FreeSql.Propagation.Requierd">
|
||||
<member name="F:FreeSql.Propagation.Required">
|
||||
<summary>
|
||||
如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,默认的选择。
|
||||
</summary>
|
||||
@ -451,6 +444,11 @@
|
||||
以嵌套事务方式执行。
|
||||
</summary>
|
||||
</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}})">
|
||||
<summary>
|
||||
EFCore 95% 相似的 FluentApi 扩展方法
|
||||
|
@ -1645,6 +1645,15 @@
|
||||
<typeparam name="TDto"></typeparam>
|
||||
<returns></returns>
|
||||
</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}})">
|
||||
<summary>
|
||||
执行SQL查询,返回指定字段的记录的第一条记录,记录不存在时返回 TReturn 默认值
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using FreeSql.Internal.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
@ -56,6 +57,14 @@ namespace FreeSql
|
||||
/// <typeparam name="TDto"></typeparam>
|
||||
/// <returns></returns>
|
||||
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>
|
||||
/// 执行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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, TReturn>> select);
|
||||
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 First<TReturn>(Expression<Func<T1, T2, TReturn>> select);
|
||||
|
@ -32,6 +32,7 @@ namespace FreeSql
|
||||
DataTable ToDataTable<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TReturn>> select);
|
||||
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 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);
|
||||
List<TReturn> ToList<TReturn>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TReturn>> select);
|
||||
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 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(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)
|
||||
{
|
||||
|
@ -174,7 +174,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
_tables[0].Parameter = select.Parameters[0];
|
||||
return this.InternalToList<TReturn>(select.Body);
|
||||
}
|
||||
|
||||
public List<TDto> ToList<TDto>() => ToList(GetToListDtoSelector<TDto>());
|
||||
Expression<Func<T1, TDto>> GetToListDtoSelector<TDto>()
|
||||
{
|
||||
@ -182,6 +181,12 @@ namespace FreeSql.Internal.CommonProvider
|
||||
typeof(TDto).InternalNewExpression(),
|
||||
_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)
|
||||
{
|
||||
|
@ -94,7 +94,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToList<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
List<TDto> ISelect<T1, T2>.ToList<TDto>() => (this as ISelect<T1, T2>).ToList(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"),
|
||||
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)
|
||||
{
|
||||
|
@ -97,7 +97,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
return this.InternalToList<TReturn>(select?.Body);
|
||||
}
|
||||
|
||||
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>()
|
||||
{
|
||||
@ -107,6 +106,12 @@ namespace FreeSql.Internal.CommonProvider
|
||||
Expression.Parameter(typeof(T2), "b"),
|
||||
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)
|
||||
{
|
||||
|
@ -100,7 +100,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
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>());
|
||||
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(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)
|
||||
{
|
||||
|
@ -103,7 +103,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
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>());
|
||||
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(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)
|
||||
{
|
||||
|
@ -106,7 +106,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
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>());
|
||||
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(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)
|
||||
{
|
||||
|
@ -109,7 +109,6 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
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>());
|
||||
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(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)
|
||||
{
|
||||
|
@ -112,9 +112,7 @@ namespace FreeSql.Internal.CommonProvider
|
||||
for (var a = 0; a < select.Parameters.Count; a++) _tables[a].Parameter = select.Parameters[a];
|
||||
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>());
|
||||
|
||||
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>>(
|
||||
@ -128,6 +126,12 @@ namespace FreeSql.Internal.CommonProvider
|
||||
Expression.Parameter(typeof(T7), "g"),
|
||||
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)
|
||||
{
|
||||
|
@ -130,6 +130,12 @@ namespace FreeSql.Internal.CommonProvider
|
||||
Expression.Parameter(typeof(T8), "h"),
|
||||
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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user