mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 优化 ISelect.GroupBy 查询,增加 .Value 实现聚合源字段查询,ToList(a => a.Sum(a.Value.Score));
- 增加 Expression string.Concat;
This commit is contained in:
		@@ -726,7 +726,7 @@ namespace FreeSql.Internal {
 | 
			
		||||
							case ExpressionType.MemberAccess:
 | 
			
		||||
								
 | 
			
		||||
								var exp2Type = exp2.Type;
 | 
			
		||||
								if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.FirstOrDefault() ?? exp2.Type;
 | 
			
		||||
								if (exp2Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) exp2Type = exp2Type.GenericTypeArguments.LastOrDefault() ?? exp2.Type;
 | 
			
		||||
								var tb2tmp = _common.GetTableByEntity(exp2Type);
 | 
			
		||||
								var mp2 = exp2 as MemberExpression;
 | 
			
		||||
								if (mp2?.Member.Name == "Key" && mp2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) continue;
 | 
			
		||||
@@ -794,7 +794,7 @@ namespace FreeSql.Internal {
 | 
			
		||||
				left = tmp;
 | 
			
		||||
			}
 | 
			
		||||
			if (right == "NULL") tryoper = tryoper == "=" ? " IS " : " IS NOT ";
 | 
			
		||||
			if (tryoper == "+" && (expBinary.Left.Type.FullName == "System.String" || expBinary.Right.Type.FullName == "System.String")) return _common.StringConcat(left, right, expBinary.Left.Type, expBinary.Right.Type);
 | 
			
		||||
			if (tryoper == "+" && (expBinary.Left.Type.FullName == "System.String" || expBinary.Right.Type.FullName == "System.String")) return _common.StringConcat(new[] { left, right }, new[] { expBinary.Left.Type, expBinary.Right.Type });
 | 
			
		||||
			if (tryoper == "%") return _common.Mod(left, right, expBinary.Left.Type, expBinary.Right.Type);
 | 
			
		||||
			if (_common._orm.Ado.DataType == DataType.MySql) {
 | 
			
		||||
				//处理c#变态enum convert, a.EnumType1 == Xxx.Xxx,被转成了 Convert(a.EnumType1, Int32) == 1
 | 
			
		||||
 
 | 
			
		||||
@@ -679,14 +679,14 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
		protected TMember InternalSum<TMember>(Expression exp) => this.ToList<TMember>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault();
 | 
			
		||||
		async protected Task<TMember> InternalSumAsync<TMember>(Expression exp) => (await this.ToListAsync<TMember>($"sum({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})")).FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
		protected ISelectGrouping<TKey> InternalGroupBy<TKey>(Expression columns) {
 | 
			
		||||
		protected 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);
 | 
			
		||||
			this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null);
 | 
			
		||||
			return new SelectGroupingProvider<TKey>(this, map, _commonExpression);
 | 
			
		||||
			return new SelectGroupingProvider<TKey, TValue>(this, map, _commonExpression, _tables);
 | 
			
		||||
		}
 | 
			
		||||
		protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) {
 | 
			
		||||
			_commonExpression.ExpressionJoinLambda(_tables, joinType, exp, null);
 | 
			
		||||
 
 | 
			
		||||
@@ -44,10 +44,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> (exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -87,10 +87,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
 | 
			
		||||
		public abstract ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> From<T2, T3, T4, T5, T6, T7, T8, T9, T10>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, ISelectFromExpression<T1>>> exp) where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class;// { this.InternalFrom(exp?.Body); var ret = new Select10Provider<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(_orm, _commonUtils, _commonExpression, null); Select0Provider<ISelect<T1>, T1>.CopyData(this, ret, exp?.Parameters); return ret; }
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<TKey> GroupBy<TKey>(Expression<Func<T1, TKey>> columns) {
 | 
			
		||||
			if (columns == null) return this.InternalGroupBy<TKey>(columns);
 | 
			
		||||
		public ISelectGrouping<TKey, T1> GroupBy<TKey>(Expression<Func<T1, TKey>> columns) {
 | 
			
		||||
			if (columns == null) return this.InternalGroupBy<TKey, T1>(columns);
 | 
			
		||||
			_tables[0].Parameter = columns.Parameters[0];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(columns);
 | 
			
		||||
			return this.InternalGroupBy<TKey, T1>(columns);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public TMember Max<TMember>(Expression<Func<T1, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -28,10 +28,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2>.GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2)> ISelect<T1, T2>.GroupBy<TKey>(Expression<Func<T1, T2, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2>.Max<TMember>(Expression<Func<T1, T2, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,10 +30,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3>.GroupBy<TKey>(Expression<Func<T1, T2, T3, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3)> ISelect<T1, T2, T3>.GroupBy<TKey>(Expression<Func<T1, T2, T3, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3>.Max<TMember>(Expression<Func<T1, T2, T3, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -32,10 +32,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4)> ISelect<T1, T2, T3, T4>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4>.Max<TMember>(Expression<Func<T1, T2, T3, T4, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -34,10 +34,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4, T5)> ISelect<T1, T2, T3, T4, T5>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4, T5>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -36,10 +36,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6)> ISelect<T1, T2, T3, T4, T5, T6>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4, T5, T6>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,10 +38,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7)> ISelect<T1, T2, T3, T4, T5, T6, T7>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4, T5, T6, T7>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -40,10 +40,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)> ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -42,10 +42,10 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return this.InternalAvgAsync<TMember>(column?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ISelectGrouping<TKey> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
		ISelectGrouping<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)> ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.GroupBy<TKey>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TKey>> exp) {
 | 
			
		||||
			if (exp == null) return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)>(exp?.Body);
 | 
			
		||||
			for (var a = 0; a < exp.Parameters.Count; a++) _tables[a].Parameter = exp.Parameters[a];
 | 
			
		||||
			return this.InternalGroupBy<TKey>(exp?.Body);
 | 
			
		||||
			return this.InternalGroupBy<TKey, (T1, T2, T3, T4, T5, T6, T7, T8, T9)>(exp?.Body);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		TMember ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9>.Max<TMember>(Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TMember>> column) {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,48 +8,89 @@ using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
	class SelectGroupingProvider<T1> : ISelectGrouping<T1> {
 | 
			
		||||
	class SelectGroupingProvider<TKey, TValue> : ISelectGrouping<TKey, TValue> {
 | 
			
		||||
 | 
			
		||||
		internal object _select;
 | 
			
		||||
		internal ReadAnonymousTypeInfo _map;
 | 
			
		||||
		internal CommonExpression _comonExp;
 | 
			
		||||
		public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp) {
 | 
			
		||||
		internal List<SelectTableInfo> _tables;
 | 
			
		||||
		public SelectGroupingProvider(object select, ReadAnonymousTypeInfo map, CommonExpression comonExp, List<SelectTableInfo> tables) {
 | 
			
		||||
			_select = select;
 | 
			
		||||
			_map = map;
 | 
			
		||||
			_comonExp = comonExp;
 | 
			
		||||
			_tables = tables;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		string getSelectGroupingMapString(Expression[] members) {
 | 
			
		||||
			var read = _map;
 | 
			
		||||
			for (var a = 0; a < members.Length; a++) {
 | 
			
		||||
				read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault();
 | 
			
		||||
				if (read == null) return null;
 | 
			
		||||
			if (members.Any() == false) return _map.DbField;
 | 
			
		||||
			var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name;
 | 
			
		||||
			switch(parentName) {
 | 
			
		||||
				case "Key":
 | 
			
		||||
					var read = _map;
 | 
			
		||||
					for (var a = 0; a < members.Length; a++) {
 | 
			
		||||
						read = read.Childs.Where(z => z.CsName == (members[a] as MemberExpression)?.Member.Name).FirstOrDefault();
 | 
			
		||||
						if (read == null) return null;
 | 
			
		||||
					}
 | 
			
		||||
					return read.DbField;
 | 
			
		||||
				case "Value":
 | 
			
		||||
					var tb = _tables.First();
 | 
			
		||||
					var foridx = 0;
 | 
			
		||||
					if (members.Length > 1) {
 | 
			
		||||
						var mem0 = (members.FirstOrDefault() as MemberExpression);
 | 
			
		||||
						var mem0Name = mem0?.Member.Name;
 | 
			
		||||
						if (mem0Name?.StartsWith("Item") == true && int.TryParse(mem0Name.Substring(4), out var tryitemidx)) {
 | 
			
		||||
							if (tryitemidx == 1) foridx++;
 | 
			
		||||
							else {
 | 
			
		||||
								var alias = $"SP10{(char)(96 + tryitemidx)}";
 | 
			
		||||
								var tmptb = _tables.Where(a => a.AliasInit == alias && a.Table.Type == mem0.Type).FirstOrDefault();
 | 
			
		||||
								if (tmptb != null) {
 | 
			
		||||
									tb = tmptb;
 | 
			
		||||
									foridx++;
 | 
			
		||||
								}
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					var parmExp = Expression.Parameter(tb.Table.Type, tb.Alias);
 | 
			
		||||
					Expression retExp = parmExp;
 | 
			
		||||
					for (var a = foridx; a < members.Length; a++) {
 | 
			
		||||
						switch(members[a].NodeType) {
 | 
			
		||||
							case ExpressionType.Call:
 | 
			
		||||
								retExp = Expression.Call(retExp, (members[a] as MethodCallExpression).Method);
 | 
			
		||||
								break;
 | 
			
		||||
							case ExpressionType.MemberAccess:
 | 
			
		||||
								retExp = Expression.MakeMemberAccess(retExp, (members[a] as MemberExpression).Member);
 | 
			
		||||
								break;
 | 
			
		||||
							default:
 | 
			
		||||
								return null;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					return _comonExp.ExpressionLambdaToSql(retExp, _tables, null, null, SelectTableInfoType.From, true, true, CommonExpression.ExpressionStyle.Where);
 | 
			
		||||
			}
 | 
			
		||||
			return read.DbField;
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<T1> Having(Expression<Func<ISelectGroupingAggregate<T1>, bool>> exp) {
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> Having(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, bool>> exp) {
 | 
			
		||||
			var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString);
 | 
			
		||||
			var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) });
 | 
			
		||||
			method.Invoke(_select, new object[] { sql, null });
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<T1> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<T1>, TMember>> column) {
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> OrderBy<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column) {
 | 
			
		||||
			var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString);
 | 
			
		||||
			var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
 | 
			
		||||
			method.Invoke(_select, new object[] { sql, null });
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<T1> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<T1>, TMember>> column) {
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> OrderByDescending<TMember>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TMember>> column) {
 | 
			
		||||
			var sql = _comonExp.ExpressionWhereLambda(null, column, getSelectGroupingMapString);
 | 
			
		||||
			var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
 | 
			
		||||
			method.Invoke(_select, new object[] { $"{sql} DESC", null });
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public List<TReturn> ToList<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) {
 | 
			
		||||
		public List<TReturn> ToList<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select) {
 | 
			
		||||
			var map = new ReadAnonymousTypeInfo();
 | 
			
		||||
			var field = new StringBuilder();
 | 
			
		||||
			var index = 0;
 | 
			
		||||
@@ -59,7 +100,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			method = method.MakeGenericMethod(typeof(TReturn));
 | 
			
		||||
			return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List<TReturn>;
 | 
			
		||||
		}
 | 
			
		||||
		public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) {
 | 
			
		||||
		public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select) {
 | 
			
		||||
			var map = new ReadAnonymousTypeInfo();
 | 
			
		||||
			var field = new StringBuilder();
 | 
			
		||||
			var index = 0;
 | 
			
		||||
@@ -70,7 +111,7 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task<List<TReturn>>;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) {
 | 
			
		||||
		public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select) {
 | 
			
		||||
			var map = new ReadAnonymousTypeInfo();
 | 
			
		||||
			var field = new StringBuilder();
 | 
			
		||||
			var index = 0;
 | 
			
		||||
@@ -80,21 +121,21 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
			return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<T1> Skip(int offset) {
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> Skip(int offset) {
 | 
			
		||||
			var method = _select.GetType().GetMethod("Skip", new[] { typeof(int) });
 | 
			
		||||
			method.Invoke(_select, new object[] { offset });
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
		public ISelectGrouping<T1> Offset(int offset) => this.Skip(offset);
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> Offset(int offset) => this.Skip(offset);
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<T1> Limit(int limit) {
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> Limit(int limit) {
 | 
			
		||||
			var method = _select.GetType().GetMethod("Limit", new[] { typeof(int) });
 | 
			
		||||
			method.Invoke(_select, new object[] { limit });
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
		public ISelectGrouping<T1> Take(int limit) => this.Limit(limit);
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> Take(int limit) => this.Limit(limit);
 | 
			
		||||
 | 
			
		||||
		public ISelectGrouping<T1> Page(int pageIndex, int pageSize) {
 | 
			
		||||
		public ISelectGrouping<TKey, TValue> Page(int pageIndex, int pageSize) {
 | 
			
		||||
			var method = _select.GetType().GetMethod("Page", new[] { typeof(int), typeof(int) });
 | 
			
		||||
			method.Invoke(_select, new object[] { pageIndex, pageSize });
 | 
			
		||||
			return this;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ namespace FreeSql.Internal {
 | 
			
		||||
		internal abstract string QuoteSqlName(string name);
 | 
			
		||||
		internal abstract string QuoteParamterName(string name);
 | 
			
		||||
		internal abstract string IsNull(string sql, object value);
 | 
			
		||||
		internal abstract string StringConcat(string left, string right, Type leftType, Type rightType);
 | 
			
		||||
		internal abstract string StringConcat(string[] objs, Type[] types);
 | 
			
		||||
		internal abstract string Mod(string left, string right, Type leftType, Type rightType);
 | 
			
		||||
		internal abstract string QuoteWriteParamter(Type type, string paramterName);
 | 
			
		||||
		internal abstract string QuoteReadColumn(Type type, string columnName);
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,16 @@
 | 
			
		||||
namespace FreeSql.Internal.Model {
 | 
			
		||||
	class SelectTableInfo {
 | 
			
		||||
		public TableInfo Table { get; set; }
 | 
			
		||||
		public string Alias { get; set; }
 | 
			
		||||
 | 
			
		||||
		private string _alias;
 | 
			
		||||
		public string Alias {
 | 
			
		||||
			get => _alias;
 | 
			
		||||
			set {
 | 
			
		||||
				_alias = value;
 | 
			
		||||
				if (string.IsNullOrEmpty(AliasInit)) AliasInit = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public string AliasInit { get; set; }
 | 
			
		||||
		public string On { get; set; }
 | 
			
		||||
		public string NavigateCondition { get; set; }
 | 
			
		||||
		public ParameterExpression Parameter { get; set; }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user