From d88b465022e70ced99b0c8d359f58d53a7ec4445 Mon Sep 17 00:00:00 2001
From: 2881099 <2881099@qq.com>
Date: Tue, 3 Nov 2020 12:00:24 +0800
Subject: [PATCH] - debug code
---
.../FreeSql.Extensions.Linq.csproj | 6 +-
.../SelectedQueryProvider.cs | 175 ++++++++++++++++++
FreeSql/Internal/CommonExpression.cs | 96 +++++-----
.../SelectProvider/SelectGroupingProvider.cs | 6 +-
4 files changed, 233 insertions(+), 50 deletions(-)
create mode 100644 Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs
diff --git a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj
index f3f175c5..f11ca82d 100644
--- a/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj
+++ b/Extensions/FreeSql.Extensions.Linq/FreeSql.Extensions.Linq.csproj
@@ -29,7 +29,11 @@
FreeSql.Extensions.Linq.xml
3
-
+
+
+ net40
+
+
diff --git a/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs
new file mode 100644
index 00000000..8d58c3c9
--- /dev/null
+++ b/Extensions/FreeSql.Extensions.Linq/SelectedQueryProvider.cs
@@ -0,0 +1,175 @@
+using FreeSql.Internal.Model;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.Common;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace FreeSql
+{
+ public interface ISelectedQuery
+ {
+#if net40
+#else
+ Task> ToListAsync();
+ Task ToOneAsync();
+ Task FirstAsync();
+
+ Task AnyAsync();
+ Task CountAsync();
+#endif
+
+ List ToList();
+ TOut ToOne();
+ TOut First();
+
+ string ToSql();
+ bool Any();
+
+ long Count();
+ ISelectedQuery Count(out long count);
+
+ ISelectedQuery Skip(int offset);
+ ISelectedQuery Offset(int offset);
+ ISelectedQuery Limit(int limit);
+ ISelectedQuery Take(int limit);
+ ISelectedQuery Page(int pageNumber, int pageSize);
+
+ ISelectedQuery Where(Expression> exp);
+ ISelectedQuery WhereIf(bool condition, Expression> exp);
+
+ ISelectedQuery OrderBy(Expression> column);
+ ISelectedQuery OrderByIf(bool condition, Expression> column, bool descending = false);
+ ISelectedQuery OrderByDescending(Expression> column);
+ }
+}
+
+namespace FreeSql.Internal.CommonProvider
+{
+ public class SelectedQueryProvider : BaseDiyMemberExpression, ISelectedQuery
+ {
+ public Select0Provider _select;
+ public CommonExpression _comonExp;
+ public SelectedQueryProvider(Select0Provider select, Expression selector)
+ {
+ _select = select;
+ _comonExp = _select._commonExpression;
+ _map = new ReadAnonymousTypeInfo();
+ var field = new StringBuilder();
+ var index = -10000; //临时规则,不返回 as1
+
+ if (selector != null)
+ _comonExp.ReadAnonymousField(_select._tables, field, _map, ref index, selector, null, null, _select._whereGlobalFilter, null, false); //不走 DTO 映射,不处理 IncludeMany
+ _field = field.ToString();
+ }
+
+ public override string ParseExp(Expression[] members)
+ {
+ if (members.Any() == false) return _map.DbField;
+ 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;
+ }
+
+#if net40
+#else
+ public Task> ToListAsync()
+ {
+ var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic);
+ method = method.MakeGenericMethod(typeof(TOut));
+ return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(_map, _field.Length > 0 ? _field.Remove(0, 2).ToString() : null) }) as Task>;
+ }
+ async public Task ToOneAsync() => (await ToListAsync()).FirstOrDefault();
+ public Task FirstAsync() => ToOneAsync();
+
+ public Task AnyAsync()
+ {
+ var method = _select.GetType().GetMethod("AnyAsync", new Type[0]);
+ return method.Invoke(_select, new object[0]) as Task;
+ }
+ public Task CountAsync()
+ {
+ var method = _select.GetType().GetMethod("CountAsync", new Type[0]);
+ return method.Invoke(_select, new object[0]) as Task;
+ }
+#endif
+
+ public List ToList()
+ {
+ var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic);
+ method = method.MakeGenericMethod(typeof(TOut));
+ return method.Invoke(_select, new object[] { new ReadAnonymousTypeAfInfo(_map, _field.Length > 0 ? _field.Remove(0, 2).ToString() : null) }) as List;
+ }
+ public TOut ToOne() => ToList().FirstOrDefault();
+ public TOut First() => ToOne();
+
+ public string ToSql()
+ {
+ var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) });
+ return method.Invoke(_select, new object[] { _field.Length > 0 ? _field.Remove(0, 2).ToString() : null }) as string;
+ }
+
+ public bool Any()
+ {
+ var method = _select.GetType().GetMethod("Any", new Type[0]);
+ return (bool)method.Invoke(_select, new object[0]);
+ }
+ public long Count()
+ {
+ var method = _select.GetType().GetMethod("Count", new Type[0]);
+ return (long)method.Invoke(_select, new object[0]);
+ }
+ public ISelectedQuery Count(out long count)
+ {
+ count = this.Count();
+ return this;
+ }
+
+ public ISelectedQuery Skip(int offset)
+ {
+ _select._skip = offset;
+ return this;
+ }
+ public ISelectedQuery Offset(int offset) => Skip(offset);
+ public ISelectedQuery Limit(int limit) => Take(limit);
+ public ISelectedQuery Take(int limit)
+ {
+ _select._limit = limit;
+ return this;
+ }
+ public ISelectedQuery Page(int pageNumber, int pageSize)
+ {
+ this.Skip(Math.Max(0, pageNumber - 1) * pageSize);
+ return this.Limit(pageSize);
+ }
+
+ public ISelectedQuery OrderBy(Expression> column) => OrderByIf(true, column);
+ public ISelectedQuery OrderByIf(bool condition, Expression> column, bool descending = false)
+ {
+ if (condition == false) return this;
+ var sql = _comonExp.ExpressionWhereLambda(null, column, this, null, null);
+ var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
+ method.Invoke(_select, new object[] { descending ? $"{sql} DESC" : sql, null });
+ return this;
+ }
+ public ISelectedQuery OrderByDescending(Expression> column) => OrderByIf(true, column, true);
+
+ public ISelectedQuery Where(Expression> exp) => WhereIf(true, exp);
+ public ISelectedQuery WhereIf(bool condition, Expression> exp)
+ {
+ if (condition == false) return this;
+ var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null);
+ var method = _select.GetType().GetMethod("Where", new[] { typeof(string), typeof(object) });
+ method.Invoke(_select, new object[] { sql, null });
+ return this;
+ }
+ }
+}
diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs
index 44df11aa..ca0880af 100644
--- a/FreeSql/Internal/CommonExpression.cs
+++ b/FreeSql/Internal/CommonExpression.cs
@@ -16,6 +16,13 @@ using System.Threading;
namespace FreeSql.Internal
{
+ public abstract class BaseDiyMemberExpression
+ {
+ public ReadAnonymousTypeInfo _map;
+ public string _field;
+ public abstract string ParseExp(Expression[] members);
+ }
+
public abstract class CommonExpression
{
@@ -28,13 +35,13 @@ namespace FreeSql.Internal
}
internal const int ReadAnonymousFieldAsCsName = -53129;
- public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, SelectGroupingProvider grouping, List whereGlobalFilter, List findIncludeMany, bool isAllDtoMap)
+ public bool ReadAnonymousField(List _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Select0Provider select, BaseDiyMemberExpression diymemexp, List whereGlobalFilter, List findIncludeMany, bool isAllDtoMap)
{
- Func getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决
+ Func getTSC = () => new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = select?._params }; //#462 添加 DbParams 解决
switch (exp.NodeType)
{
- case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap);
- case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap);
+ case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
+ case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
case ExpressionType.Negate:
case ExpressionType.NegateChecked:
parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})";
@@ -43,7 +50,7 @@ namespace FreeSql.Internal
else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName));
if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type;
return false;
- case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap);
+ case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
case ExpressionType.Constant:
var constExp = exp as ConstantExpression;
//处理自定义SQL语句,如: ToList(new {
@@ -93,7 +100,7 @@ namespace FreeSql.Internal
{
//加载表所有字段
var map = new List();
- ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, grouping);
+ ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, diymemexp);
var tb = parent.Table = map.First().Table.Table;
parent.CsType = tb.Type;
parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst();
@@ -133,7 +140,7 @@ namespace FreeSql.Internal
MapType = memProp.PropertyType
};
parent.Childs.Add(child);
- ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, grouping, whereGlobalFilter, findIncludeMany, false);
+ ReadAnonymousField(_tables, field, child, ref index, Expression.MakeMemberAccess(exp, memProp), select, diymemexp, whereGlobalFilter, findIncludeMany, false);
}
}
}
@@ -163,11 +170,11 @@ namespace FreeSql.Internal
}
}
}
- if (grouping != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`"))
+ if (diymemexp != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`"))
{
- field.Append(grouping._field);
+ field.Append(diymemexp._field);
var parentProp = parent.Property;
- grouping._map.CopyTo(parent);
+ diymemexp._map.CopyTo(parent);
parent.Property = parentProp; //若不加此行,会引用 GroupBy(..).ToList(a => new Dto { key = a.Key }) null 错误,CopyTo 之后 Property 变为 null
return false;
}
@@ -199,7 +206,7 @@ namespace FreeSql.Internal
MapType = initExp.NewExpression.Arguments[a].Type
};
parent.Childs.Add(child);
- ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, grouping, whereGlobalFilter, findIncludeMany, false);
+ ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, false);
}
}
else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type)
@@ -224,7 +231,7 @@ namespace FreeSql.Internal
};
parent.Childs.Add(child);
if (dtTb.Parameter != null)
- ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap);
+ ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
else
{
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
@@ -250,7 +257,7 @@ namespace FreeSql.Internal
MapType = initAssignExp.Expression.Type
};
parent.Childs.Add(child);
- ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, grouping, whereGlobalFilter, findIncludeMany, false);
+ ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, select, diymemexp, whereGlobalFilter, findIncludeMany, false);
}
}
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同");
@@ -283,7 +290,7 @@ namespace FreeSql.Internal
MapType = newExp.Arguments[a].Type
};
parent.Childs.Add(child);
- ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, grouping, whereGlobalFilter, findIncludeMany, false);
+ ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], select, diymemexp, whereGlobalFilter, findIncludeMany, false);
}
}
else
@@ -307,7 +314,7 @@ namespace FreeSql.Internal
};
parent.Childs.Add(child);
if (dtTb.Parameter != null)
- ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, grouping, whereGlobalFilter, findIncludeMany, isAllDtoMap);
+ ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
else
{
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
@@ -404,32 +411,32 @@ namespace FreeSql.Internal
return null;
}
- public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, SelectGroupingProvider grouping)
+ public string ExpressionSelectColumn_MemberAccess(List _tables, List _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, BaseDiyMemberExpression diymemexp)
{
- return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = grouping, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns });
+ return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, diymemexp = diymemexp, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns });
}
- public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, SelectGroupingProvider grouping)
+ public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List _tables, Expression exp, bool isQuoteName, BaseDiyMemberExpression diymemexp)
{
switch (exp?.NodeType)
{
- case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, grouping);
- case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, grouping);
- case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, grouping);
- case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping) };
+ case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, diymemexp);
+ case ExpressionType.Lambda: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as LambdaExpression)?.Body, isQuoteName, diymemexp);
+ case ExpressionType.Convert: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, diymemexp);
+ case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, diymemexp) };
case ExpressionType.Call:
- case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries);
+ case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, diymemexp).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries);
case ExpressionType.New:
var newExp = exp as NewExpression;
if (newExp == null) break;
var newExpMembers = new string[newExp.Members.Count];
- for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, grouping);
+ for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, diymemexp);
return newExpMembers.Distinct().Select(a => a.Trim('\'')).ToArray();
case ExpressionType.NewArrayInit:
var newArr = exp as NewArrayExpression;
if (newArr == null) break;
var newArrMembers = new List();
- foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, grouping));
+ foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, diymemexp));
return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray();
default: throw new ArgumentException($"无法解析表达式:{exp}");
}
@@ -454,22 +461,22 @@ namespace FreeSql.Internal
{ ExpressionType.Equal, "=" },
};
- public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, SelectGroupingProvider groupingProvider, List dbParams)
+ public string ExpressionWhereLambdaNoneForeignObject(List _tables, TableInfo table, List _selectColumnMap, Expression exp, BaseDiyMemberExpression diymemexp, List dbParams)
{
- var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams });
+ var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = dbParams });
return GetBoolString(exp, sql);
}
- public string ExpressionWhereLambda(List _tables, Expression exp, SelectGroupingProvider groupingProvider, List whereGlobalFilter, List dbParams)
+ public string ExpressionWhereLambda(List _tables, Expression exp, BaseDiyMemberExpression diymemexp, List whereGlobalFilter, List dbParams)
{
- var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = dbParams });
+ var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter, dbParams = dbParams });
return GetBoolString(exp, sql);
}
static ConcurrentDictionary dicRegexAlias = new ConcurrentDictionary();
- public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, SelectGroupingProvider groupingProvider, List whereGlobalFilter)
+ public void ExpressionJoinLambda(List _tables, SelectTableInfoType tbtype, Expression exp, BaseDiyMemberExpression diymemexp, List whereGlobalFilter)
{
var tbidx = _tables.Count;
- var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter });
+ var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, diymemexp = diymemexp, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereGlobalFilter = whereGlobalFilter });
sql = GetBoolString(exp, sql);
if (_tables.Count > tbidx)
@@ -891,7 +898,7 @@ namespace FreeSql.Internal
var testExecuteExp = asSelectParentExp;
if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联
testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key);
- var tsc2 = tsc.CloneSetselectColumnMapAndgroupingAndtbtype(new List(), tsc.grouping, SelectTableInfoType.LeftJoin);
+ var tsc2 = tsc.Clone_selectColumnMap_diymemexp_tbtype(new List(), tsc.diymemexp, SelectTableInfoType.LeftJoin);
tsc2.isDisableDiyParse = true;
tsc2.style = ExpressionStyle.AsSelect;
asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2);
@@ -1253,13 +1260,12 @@ namespace FreeSql.Internal
return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
}
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
- if (tsc.grouping != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`"))
+ if (tsc.diymemexp != null)
{
- if (tsc.grouping != null)
- {
- var expText = tsc.grouping.GetSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray());
- if (string.IsNullOrEmpty(expText) == false) return expText;
- }
+ var expStackFirst = expStack.First();
+ var bidx = expStackFirst.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`") ? 2 : 1; //.Key .Value
+ var expText = tsc.diymemexp.ParseExp(expStack.Where((a, b) => b >= bidx).ToArray());
+ if (string.IsNullOrEmpty(expText) == false) return expText;
}
if (tsc._tables == null)
@@ -1367,9 +1373,9 @@ namespace FreeSql.Internal
if (find.Type == SelectTableInfoType.InnerJoin ||
find.Type == SelectTableInfoType.LeftJoin ||
find.Type == SelectTableInfoType.RightJoin)
- find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type));
+ find.On = ExpressionLambdaToSql(navCondExp, tsc.Clone_selectColumnMap_diymemexp_tbtype(null, null, find.Type));
else
- find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type));
+ find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.Clone_selectColumnMap_diymemexp_tbtype(null, null, find.Type));
}
}
}
@@ -1515,7 +1521,7 @@ namespace FreeSql.Internal
{
public List _tables { get; set; }
public List _selectColumnMap { get; set; }
- public SelectGroupingProvider grouping { get; set; }
+ public BaseDiyMemberExpression diymemexp { get; set; }
public Select0Provider subSelect001 { get; set; } //#405 Oracle within group(order by ..)
public SelectTableInfoType tbtype { get; set; }
public bool isQuoteName { get; set; }
@@ -1556,13 +1562,13 @@ namespace FreeSql.Internal
return old;
}
- public ExpTSC CloneSetselectColumnMapAndgroupingAndtbtype(List v1, SelectGroupingProvider v2, SelectTableInfoType v3)
+ public ExpTSC Clone_selectColumnMap_diymemexp_tbtype(List v1, BaseDiyMemberExpression v2, SelectTableInfoType v3)
{
return new ExpTSC
{
_tables = this._tables,
_selectColumnMap = v1,
- grouping = v2,
+ diymemexp = v2,
tbtype = v3,
isQuoteName = this.isQuoteName,
isDisableDiyParse = this.isDisableDiyParse,
@@ -1582,7 +1588,7 @@ namespace FreeSql.Internal
{
_tables = this._tables,
_selectColumnMap = this._selectColumnMap,
- grouping = this.grouping,
+ diymemexp = this.diymemexp,
subSelect001 = this.subSelect001,
tbtype = this.tbtype,
isQuoteName = this.isQuoteName,
@@ -1626,7 +1632,7 @@ namespace FreeSql.Internal
);
var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables =
isMultitb ? new List(new[] { tb }) : null,
- _selectColumnMap = null, grouping = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias });
+ _selectColumnMap = null, diymemexp = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias });
whereSql = GetBoolString(expExp.Body, whereSql);
if (isEmpty == false)
sb.Append(" AND ");
diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs
index 25694049..33299b9f 100644
--- a/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs
+++ b/FreeSql/Internal/CommonProvider/SelectProvider/SelectGroupingProvider.cs
@@ -11,12 +11,10 @@ using System.Threading.Tasks;
namespace FreeSql.Internal.CommonProvider
{
- public class SelectGroupingProvider
+ public class SelectGroupingProvider : BaseDiyMemberExpression
{
public IFreeSql _orm;
public Select0Provider _select;
- public ReadAnonymousTypeInfo _map;
- public string _field;
public CommonExpression _comonExp;
public List _tables;
@@ -30,7 +28,7 @@ namespace FreeSql.Internal.CommonProvider
_tables = tables;
}
- public string GetSelectGroupingMapString(Expression[] members)
+ public override string ParseExp(Expression[] members)
{
if (members.Any() == false) return _map.DbField;
var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name;