From e1f81c4bc742b0bafcd149fb78515520edf084e1 Mon Sep 17 00:00:00 2001 From: Linlccc Date: Fri, 18 Jul 2025 16:40:38 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=20Group=20?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=B8=8D=E6=94=AF=E6=8C=81=20aot=20=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20perf=EF=BC=9A=E4=BC=98=E5=8C=96=E9=9D=9E=20aot=20?= =?UTF-8?q?=E4=B8=8B=E5=88=86=E7=BB=84=E6=9F=A5=E8=AF=A2=E6=80=A7=E8=83=BD?= =?UTF-8?q?=EF=BC=88=E5=87=8F=E5=B0=91=E5=8F=8D=E5=B0=84=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SelectProvider/Select0Provider.cs | 78 +++++++++++++++++++ .../SelectProvider/Select0ProviderReader.cs | 75 ++---------------- .../SelectProvider/SelectGroupingProvider.cs | 61 ++++++--------- 3 files changed, 106 insertions(+), 108 deletions(-) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index 5af61e8ca..3812675ec 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Data; using System.Data.Common; using System.Linq; using System.Linq.Expressions; @@ -87,6 +88,83 @@ public Select0Provider() public abstract string ToSqlBase(string field = null); public abstract void AsTableBase(Func tableRule); + internal virtual List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; + var dbParms = _params.ToArray(); + var type = typeof(TReturn); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var retCount = 0; + 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, retCount, af.fillIncludeMany, af.fillSubSelectMany)); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null, null)); + retCount++; + }, CommandType.Text, sql, _commandTimeout, dbParms); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + _trackToList?.Invoke(ret); + return ret; + } + #region async +#if !net40 + internal virtual async Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) + { + var ret = new List(); + if (_cancel?.Invoke() == true) return ret; + var dbParms = _params.ToArray(); + var type = typeof(TReturn); + var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); + _orm.Aop.CurdBeforeHandler?.Invoke(this, before); + var retCount = 0; + 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, retCount, af.fillIncludeMany, af.fillSubSelectMany)); + if (otherData != null) + foreach (var other in otherData) + other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null, null)); + retCount++; + return Task.FromResult(false); + }, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); + } + catch (Exception ex) + { + exception = ex; + throw; + } + finally + { + var after = new Aop.CurdAfterEventArgs(before, exception, ret); + _orm.Aop.CurdAfterHandler?.Invoke(this, after); + } + _trackToList?.Invoke(ret); + return ret; + } +#endif + #endregion + + public static void CopyData(Select0Provider from, Select0Provider to, ReadOnlyCollection lambParms) { if (to == null) return; diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs index 0358052a0..9c28a336c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0ProviderReader.cs @@ -343,41 +343,10 @@ public Dictionary ToDictionary(Func ke return ret; } - internal List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) + internal override List ToListMrPrivate(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) { - var ret = new List(); - if (_cancel?.Invoke() == true) return ret; - var dbParms = _params.ToArray(); - var type = typeof(TReturn); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var retCount = 0; - 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, retCount, af.fillIncludeMany, af.fillSubSelectMany)); - if (otherData != null) - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null, null)); - retCount++; - }, CommandType.Text, sql, _commandTimeout, dbParms); - } - catch (Exception ex) - { - exception = ex; - throw; - } - 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); + var ret = base.ToListMrPrivate(sql, af, otherData); + if (typeof(TReturn) == typeof(T1)) foreach (var include in _includeToList) include?.Invoke(ret); return ret; } internal List ToListMapReaderPrivate(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData) @@ -1377,42 +1346,10 @@ await _orm.Ado.ExecuteReaderAsync(_connection, _transaction, fetch => return ret; } - async internal Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) + internal override async Task> ToListMrPrivateAsync(string sql, ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) { - var ret = new List(); - if (_cancel?.Invoke() == true) return ret; - var dbParms = _params.ToArray(); - var type = typeof(TReturn); - var before = new Aop.CurdBeforeEventArgs(_tables[0].Table.Type, _tables[0].Table, Aop.CurdType.Select, sql, dbParms); - _orm.Aop.CurdBeforeHandler?.Invoke(this, before); - var retCount = 0; - 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, retCount, af.fillIncludeMany, af.fillSubSelectMany)); - if (otherData != null) - foreach (var other in otherData) - other.retlist.Add(_commonExpression.ReadAnonymous(other.read, fetch.Object, ref index, false, null, retCount, null, null)); - retCount++; - return Task.FromResult(false); - }, CommandType.Text, sql, _commandTimeout, dbParms, cancellationToken); - } - catch (Exception ex) - { - exception = ex; - throw; - } - 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, cancellationToken); - _trackToList?.Invoke(ret); + var ret = await base.ToListMrPrivateAsync(sql, af, otherData, cancellationToken); + if (typeof(TReturn) == typeof(T1)) foreach (var include in _includeToListAsync) await include?.Invoke(ret, cancellationToken); return ret; } internal Task> ToListMapReaderPrivateAsync(ReadAnonymousTypeAfInfo af, ReadAnonymousTypeOtherInfo[] otherData, CancellationToken cancellationToken) diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs index 20e377c3a..ffcdac94c 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs @@ -156,34 +156,6 @@ public void InternalOrderBy(Expression exp, bool isDescending) var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null }); } - public object InternalToList(Expression select, Type elementType) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _comonExp.ReadAnonymousField(null, _select._tableRule, field, map, ref index, select, _select, this, null, null, null, false); - if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; - var method = _select.GetType().GetMethod("ToListMrPrivate", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(elementType); - var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null; - return method.Invoke(_select, new object[] { InternalToSql(fieldSql), new ReadAnonymousTypeAfInfo(map, fieldSql), null }); - } - public IEnumerable> InternalToKeyValuePairs(Expression elementSelector, Type elementType) - { - var map = new ReadAnonymousTypeInfo(); - var field = new StringBuilder(); - var index = 0; - - _comonExp.ReadAnonymousField(null, _select._tableRule, field, map, ref index, elementSelector, _select, this, null, null, null, false); - if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; - var method = _select.GetType().GetMethod("ToListMrPrivate", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(elementType); - var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null; - var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); - var values = method.Invoke(_select, new object[] { InternalToSql($"{fieldSql}{_field}"), new ReadAnonymousTypeAfInfo(map, fieldSql), new[] { otherAf } }) as IList; - return otherAf.retlist.Select((a, b) => new KeyValuePair(a, values[b])); - } public string InternalToSql(Expression select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) { var map = new ReadAnonymousTypeInfo(); @@ -214,8 +186,7 @@ public string InternalToSql(string field) _select._skip = _groupBySkip; break; } - var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); - var sql = method.Invoke(_select, new object[] { field }) as string; + var sql = _select.ToSqlBase(field); if (isNestedPageSql == false) { _select._limit = 0; @@ -337,13 +308,29 @@ public ISelectGrouping OrderByDescending(Expression(Expression, TReturn>> select) => ToList(select).FirstOrDefault(); public List ToList(Expression, TReturn>> select) { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + _lambdaParameter = select?.Parameters[0]; - return InternalToList(select, typeof(TReturn)) as List; + _comonExp.ReadAnonymousField(null, _select._tableRule, field, map, ref index, select, _select, this, null, null, null, false); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TReturn); + var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null; + return _select.ToListMrPrivate(InternalToSql(fieldSql), new ReadAnonymousTypeAfInfo(map, fieldSql), null); } public Dictionary ToDictionary(Expression, TElement>> elementSelector) { + var map = new ReadAnonymousTypeInfo(); + var field = new StringBuilder(); + var index = 0; + _lambdaParameter = elementSelector?.Parameters[0]; - return InternalToKeyValuePairs(elementSelector, typeof(TElement)).ToDictionary(a => (TKey)a.Key, a => (TElement)a.Value); + _comonExp.ReadAnonymousField(null, _select._tableRule, field, map, ref index, elementSelector, _select, this, null, null, null, false); + if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); + var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null; + var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); + var values = _select.ToListMrPrivate(InternalToSql($"{fieldSql}{_field}"), new ReadAnonymousTypeAfInfo(map, fieldSql), new[] { otherAf }); + return otherAf.retlist.Select((a, b) => new KeyValuePair((TKey)a, values[b])).ToDictionary(a=>a.Key,a=>a.Value); } #if net40 @@ -360,12 +347,10 @@ public Task> ToListAsync(Expression 0 ? field.Remove(0, 2).ToString() : null; - return method.Invoke(_select, new object[] { InternalToSql(fieldSql), new ReadAnonymousTypeAfInfo(map, fieldSql), null, cancellationToken }) as Task>; + return _select.ToListMrPrivateAsync(InternalToSql(fieldSql), new ReadAnonymousTypeAfInfo(map, fieldSql), null, cancellationToken); } - async public Task> ToDictionaryAsync(Expression, TElement>> elementSelector, CancellationToken cancellationToken = default) + public async Task> ToDictionaryAsync(Expression, TElement>> elementSelector, CancellationToken cancellationToken = default) { var map = new ReadAnonymousTypeInfo(); var field = new StringBuilder(); @@ -374,11 +359,9 @@ async public Task> ToDictionaryAsync(Expres _lambdaParameter = elementSelector?.Parameters[0]; _comonExp.ReadAnonymousField(null, _select._tableRule, field, map, ref index, elementSelector, _select, this, null, null, null, false); if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); - var method = _select.GetType().GetMethod("ToListMrPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic); - method = method.MakeGenericMethod(typeof(TElement)); var fieldSql = field.Length > 0 ? field.Remove(0, 2).ToString() : null; var otherAf = new ReadAnonymousTypeOtherInfo(_field, _map, new List()); - var values = await (method.Invoke(_select, new object[] { InternalToSql($"{fieldSql}{_field}"), new ReadAnonymousTypeAfInfo(map, fieldSql), new[] { otherAf }, cancellationToken }) as Task>); + var values = await _select.ToListMrPrivateAsync(InternalToSql($"{fieldSql}{_field}"), new ReadAnonymousTypeAfInfo(map, fieldSql), new[] { otherAf }, cancellationToken); return otherAf.retlist.Select((a, b) => new KeyValuePair((TKey)a, values[b])).ToDictionary(a => a.Key, a => a.Value); } #endif