- 优化 GroupBy ToList 中可以直接使用 a.Key;

This commit is contained in:
28810 2020-08-07 00:00:39 +08:00
parent dfac943495
commit 7efe02f69c
21 changed files with 109 additions and 62 deletions

View File

@ -866,7 +866,7 @@ namespace FreeSql.Tests.MySqlConnector
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -793,7 +793,7 @@ namespace FreeSql.Tests.Odbc.Dameng
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -784,7 +784,7 @@ namespace FreeSql.Tests.Odbc.Default
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -758,7 +758,7 @@ namespace FreeSql.Tests.Odbc.KingbaseES
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -877,7 +877,7 @@ namespace FreeSql.Tests.Odbc.MySql
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -794,7 +794,7 @@ namespace FreeSql.Tests.Odbc.Oracle
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -854,7 +854,7 @@ namespace FreeSql.Tests.Odbc.PostgreSQL
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -749,7 +749,7 @@ namespace FreeSql.Tests.Odbc.SqlServer
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -793,7 +793,7 @@ namespace FreeSql.Tests.Dameng
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -785,7 +785,7 @@ namespace FreeSql.Tests.MsAccess
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -913,7 +913,7 @@ namespace FreeSql.Tests.MySql
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -794,7 +794,7 @@ namespace FreeSql.Tests.Oracle
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -871,7 +871,7 @@ namespace FreeSql.Tests.PostgreSQL
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -871,7 +871,7 @@ namespace FreeSql.Tests.ShenTong
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -805,7 +805,7 @@ namespace FreeSql.Tests.SqlServer
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -759,7 +759,7 @@ namespace FreeSql.Tests.Sqlite
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)
}); });

View File

@ -996,7 +996,7 @@ namespace FreeSql.Tests
{ {
b.Key.Title, b.Key.Title,
b.Key.yyyy, b.Key.yyyy,
b.Key,
cou = b.Count(), cou = b.Count(),
sum = b.Sum(b.Key.yyyy), sum = b.Sum(b.Key.yyyy),
sum2 = b.Sum(b.Value.TypeGuid) sum2 = b.Sum(b.Value.TypeGuid)

View File

@ -179,6 +179,17 @@ namespace FreeSql.Tests
var aff2 = g.sqlite.Delete<Edi>(10086).ExecuteAffrows(); var aff2 = g.sqlite.Delete<Edi>(10086).ExecuteAffrows();
Assert.Equal(aff1, aff2); Assert.Equal(aff1, aff2);
g.sqlserver.Delete<Edi>().Where("1=1").ExecuteAffrows();
g.sqlserver.Delete<EdiItem>().Where("1=1").ExecuteAffrows();
g.sqlserver.Insert(new[] { new Edi { Id = 1 }, new Edi { Id = 2 }, new Edi { Id = 3 }, new Edi { Id = 4 }, new Edi { Id = 5 } }).ExecuteAffrows();
g.sqlserver.Insert(new[] {
new EdiItem { Id = 1, EdiId = 1 }, new EdiItem { Id = 2, EdiId = 1 }, new EdiItem { Id = 3, EdiId = 1 } ,
new EdiItem { Id = 4, EdiId = 2 }, new EdiItem { Id = 5, EdiId = 2 },
new EdiItem { Id = 6, EdiId = 3 }, new EdiItem { Id = 7, EdiId = 3 },
new EdiItem { Id = 8, EdiId = 4 }, new EdiItem { Id = 9, EdiId = 4 },
new EdiItem { Id = 10, EdiId = 5 }, new EdiItem { Id = 11, EdiId = 5 },
}).ExecuteAffrows();
var testStringFormat = g.sqlite.Select<Edi>().First(a => new { var testStringFormat = g.sqlite.Select<Edi>().First(a => new {
str = $"x{a.Id}_{DateTime.Now.ToString("yyyyMM")}z", str = $"x{a.Id}_{DateTime.Now.ToString("yyyyMM")}z",
@ -265,6 +276,22 @@ namespace FreeSql.Tests
over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue(), over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue(),
}); });
var sqlextCaseGroupBy1 = g.sqlserver.Select<Edi, EdiItem>()
.InnerJoin((a, b) => b.Id == a.Id)
.GroupBy((a, b) => new { aid = a.Id, bid = b.Id })
.ToDictionary(a => new
{
sum = a.Sum(a.Value.Item2.EdiId)
});
var sqlextCaseGroupBy2 = g.sqlserver.Select<Edi, EdiItem>()
.InnerJoin((a, b) => b.Id == a.Id)
.GroupBy((a, b) => new { aid = a.Id, bid = b.Id })
.ToList(a => new
{
a.Key, sum = a.Sum(a.Value.Item2.EdiId)
});
var sqlextOver = g.sqlserver.Select<Edi, EdiItem>() var sqlextOver = g.sqlserver.Select<Edi, EdiItem>()
.InnerJoin((a, b) => b.Id == a.Id) .InnerJoin((a, b) => b.Id == a.Id)

View File

@ -28,13 +28,13 @@ namespace FreeSql.Internal
} }
internal const int ReadAnonymousFieldAsCsName = -53129; internal const int ReadAnonymousFieldAsCsName = -53129;
public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<LambdaExpression> whereCascadeExpression, bool isAllDtoMap) public bool ReadAnonymousField(List<SelectTableInfo> _tables, StringBuilder field, ReadAnonymousTypeInfo parent, ref int index, Expression exp, SelectGroupingProvider grouping, List<LambdaExpression> whereCascadeExpression, bool isAllDtoMap)
{ {
Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }; Func<ExpTSC> getTSC = () => new ExpTSC { _tables = _tables, grouping = grouping, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression };
switch (exp.NodeType) switch (exp.NodeType)
{ {
case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Quote: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, grouping, whereCascadeExpression, isAllDtoMap);
case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Lambda: return ReadAnonymousField(_tables, field, parent, ref index, (exp as LambdaExpression)?.Body, grouping, whereCascadeExpression, isAllDtoMap);
case ExpressionType.Negate: case ExpressionType.Negate:
case ExpressionType.NegateChecked: case ExpressionType.NegateChecked:
parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})"; parent.DbField = $"-({ExpressionLambdaToSql(exp, getTSC())})";
@ -43,7 +43,7 @@ namespace FreeSql.Internal
else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName)); 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; if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type;
return false; return false;
case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); case ExpressionType.Convert: return ReadAnonymousField(_tables, field, parent, ref index, (exp as UnaryExpression)?.Operand, grouping, whereCascadeExpression, isAllDtoMap);
case ExpressionType.Constant: case ExpressionType.Constant:
var constExp = exp as ConstantExpression; var constExp = exp as ConstantExpression;
//处理自定义SQL语句 ToList(new { //处理自定义SQL语句 ToList(new {
@ -93,7 +93,7 @@ namespace FreeSql.Internal
{ {
//加载表所有字段 //加载表所有字段
var map = new List<SelectColumnInfo>(); var map = new List<SelectColumnInfo>();
ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, getSelectGroupingMapString); ExpressionSelectColumn_MemberAccess(_tables, map, SelectTableInfoType.From, exp, true, grouping);
var tb = parent.Table = map.First().Table.Table; var tb = parent.Table = map.First().Table.Table;
parent.CsType = tb.Type; parent.CsType = tb.Type;
parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst(); parent.Consturctor = tb.Type.InternalGetTypeConstructor0OrFirst();
@ -115,6 +115,12 @@ namespace FreeSql.Internal
} }
else else
{ {
if (grouping != null && exp is MemberExpression expMem2 && expMem2.Member.Name == "Key" && expMem2.Expression.Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`"))
{
field.Append(grouping._field);
grouping._map.CopyTo(parent);
return false;
}
parent.CsType = exp.Type; parent.CsType = exp.Type;
parent.DbField = ExpressionLambdaToSql(exp, getTSC()); parent.DbField = ExpressionLambdaToSql(exp, getTSC());
field.Append(", ").Append(parent.DbField); field.Append(", ").Append(parent.DbField);
@ -141,7 +147,7 @@ namespace FreeSql.Internal
MapType = initExp.NewExpression.Arguments[a].Type MapType = initExp.NewExpression.Arguments[a].Type
}; };
parent.Childs.Add(child); parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false); ReadAnonymousField(_tables, field, child, ref index, initExp.NewExpression.Arguments[a], grouping, whereCascadeExpression, false);
} }
} }
else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type) else if (isAllDtoMap && _tables != null && _tables.Any() && initExp.NewExpression.Type != _tables.FirstOrDefault().Table.Type)
@ -164,7 +170,7 @@ namespace FreeSql.Internal
}; };
parent.Childs.Add(child); parent.Childs.Add(child);
if (dtTb.Parameter != null) if (dtTb.Parameter != null)
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), grouping, whereCascadeExpression, isAllDtoMap);
else else
{ {
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
@ -190,7 +196,7 @@ namespace FreeSql.Internal
MapType = initAssignExp.Expression.Type MapType = initAssignExp.Expression.Type
}; };
parent.Childs.Add(child); parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, getSelectGroupingMapString, whereCascadeExpression, false); ReadAnonymousField(_tables, field, child, ref index, initAssignExp.Expression, grouping, whereCascadeExpression, false);
} }
} }
if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同"); if (parent.Childs.Any() == false) throw new Exception($"映射异常:{initExp.NewExpression.Type.Name} 没有一个属性名相同");
@ -223,7 +229,7 @@ namespace FreeSql.Internal
MapType = newExp.Arguments[a].Type MapType = newExp.Arguments[a].Type
}; };
parent.Childs.Add(child); parent.Childs.Add(child);
ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], getSelectGroupingMapString, whereCascadeExpression, false); ReadAnonymousField(_tables, field, child, ref index, newExp.Arguments[a], grouping, whereCascadeExpression, false);
} }
} }
else else
@ -247,7 +253,7 @@ namespace FreeSql.Internal
}; };
parent.Childs.Add(child); parent.Childs.Add(child);
if (dtTb.Parameter != null) if (dtTb.Parameter != null)
ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), getSelectGroupingMapString, whereCascadeExpression, isAllDtoMap); ReadAnonymousField(_tables, field, child, ref index, Expression.Property(dtTb.Parameter, dtTb.Table.Properties[trydtocol.CsName]), grouping, whereCascadeExpression, isAllDtoMap);
else else
{ {
child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}"; child.DbField = $"{dtTb.Alias}.{_common.QuoteSqlName(trydtocol.Attribute.Name)}";
@ -339,32 +345,32 @@ namespace FreeSql.Internal
return null; return null;
} }
public string ExpressionSelectColumn_MemberAccess(List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) public string ExpressionSelectColumn_MemberAccess(List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, SelectTableInfoType tbtype, Expression exp, bool isQuoteName, SelectGroupingProvider grouping)
{ {
return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns }); return ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, grouping = grouping, tbtype = tbtype, isQuoteName = isQuoteName, isDisableDiyParse = false, style = ExpressionStyle.SelectColumns });
} }
public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List<SelectTableInfo> _tables, Expression exp, bool isQuoteName, Func<Expression[], string> getSelectGroupingMapString) public string[] ExpressionSelectColumns_MemberAccess_New_NewArrayInit(List<SelectTableInfo> _tables, Expression exp, bool isQuoteName, SelectGroupingProvider grouping)
{ {
switch (exp?.NodeType) switch (exp?.NodeType)
{ {
case ExpressionType.Quote: return ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, (exp as UnaryExpression)?.Operand, isQuoteName, getSelectGroupingMapString); 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, getSelectGroupingMapString); 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, getSelectGroupingMapString); 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, getSelectGroupingMapString) }; case ExpressionType.Constant: return new[] { ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping) };
case ExpressionType.Call: case ExpressionType.Call:
case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, getSelectGroupingMapString).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries); case ExpressionType.MemberAccess: return ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, isQuoteName, grouping).Trim('(', ')', '\'').Split(new[] { "','" }, StringSplitOptions.RemoveEmptyEntries);
case ExpressionType.New: case ExpressionType.New:
var newExp = exp as NewExpression; var newExp = exp as NewExpression;
if (newExp == null) break; if (newExp == null) break;
var newExpMembers = new string[newExp.Members.Count]; 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, getSelectGroupingMapString); for (var a = 0; a < newExpMembers.Length; a++) newExpMembers[a] = ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, newExp.Arguments[a], isQuoteName, grouping);
return newExpMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); return newExpMembers.Distinct().Select(a => a.Trim('\'')).ToArray();
case ExpressionType.NewArrayInit: case ExpressionType.NewArrayInit:
var newArr = exp as NewArrayExpression; var newArr = exp as NewArrayExpression;
if (newArr == null) break; if (newArr == null) break;
var newArrMembers = new List<string>(); var newArrMembers = new List<string>();
foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, getSelectGroupingMapString)); foreach (var newArrExp in newArr.Expressions) newArrMembers.AddRange(ExpressionSelectColumns_MemberAccess_New_NewArrayInit(_tables, newArrExp, isQuoteName, grouping));
return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray(); return newArrMembers.Distinct().Select(a => a.Trim('\'')).ToArray();
default: throw new ArgumentException($"无法解析表达式:{exp}"); default: throw new ArgumentException($"无法解析表达式:{exp}");
} }
@ -389,22 +395,22 @@ namespace FreeSql.Internal
{ ExpressionType.Equal, "=" }, { ExpressionType.Equal, "=" },
}; };
public string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<DbParameter> dbParams) public string ExpressionWhereLambdaNoneForeignObject(List<SelectTableInfo> _tables, TableInfo table, List<SelectColumnInfo> _selectColumnMap, Expression exp, SelectGroupingProvider groupingProvider, List<DbParameter> dbParams)
{ {
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, _selectColumnMap = _selectColumnMap, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = table, dbParams = 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 });
return GetBoolString(exp, sql); return GetBoolString(exp, sql);
} }
public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<LambdaExpression> whereCascadeExpression, List<DbParameter> dbParams) public string ExpressionWhereLambda(List<SelectTableInfo> _tables, Expression exp, SelectGroupingProvider groupingProvider, List<LambdaExpression> whereCascadeExpression, List<DbParameter> dbParams)
{ {
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams }); var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression, dbParams = dbParams });
return GetBoolString(exp, sql); return GetBoolString(exp, sql);
} }
static ConcurrentDictionary<string, Regex> dicRegexAlias = new ConcurrentDictionary<string, Regex>(); static ConcurrentDictionary<string, Regex> dicRegexAlias = new ConcurrentDictionary<string, Regex>();
public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, Func<Expression[], string> getSelectGroupingMapString, List<LambdaExpression> whereCascadeExpression) public void ExpressionJoinLambda(List<SelectTableInfo> _tables, SelectTableInfoType tbtype, Expression exp, SelectGroupingProvider groupingProvider, List<LambdaExpression> whereCascadeExpression)
{ {
var tbidx = _tables.Count; var tbidx = _tables.Count;
var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, getSelectGroupingMapString = getSelectGroupingMapString, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression }); var sql = ExpressionLambdaToSql(exp, new ExpTSC { _tables = _tables, grouping = groupingProvider, tbtype = tbtype, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, whereCascadeExpression = whereCascadeExpression });
sql = GetBoolString(exp, sql); sql = GetBoolString(exp, sql);
if (_tables.Count > tbidx) if (_tables.Count > tbidx)
@ -813,7 +819,7 @@ namespace FreeSql.Internal
var testExecuteExp = asSelectParentExp; var testExecuteExp = asSelectParentExp;
if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联 if (asSelectParentExp.NodeType == ExpressionType.Parameter) //执行leftjoin关联
testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key); testExecuteExp = Expression.Property(testExecuteExp, _common.GetTableByEntity(asSelectParentExp.Type).ColumnsByCs.First().Key);
var tsc2 = tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(new List<SelectColumnInfo>(), tsc.getSelectGroupingMapString, SelectTableInfoType.LeftJoin); var tsc2 = tsc.CloneSetselectColumnMapAndgroupingAndtbtype(new List<SelectColumnInfo>(), tsc.grouping, SelectTableInfoType.LeftJoin);
tsc2.isDisableDiyParse = true; tsc2.isDisableDiyParse = true;
tsc2.style = ExpressionStyle.AsSelect; tsc2.style = ExpressionStyle.AsSelect;
asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2); asSelectSql = ExpressionLambdaToSql(testExecuteExp, tsc2);
@ -1167,11 +1173,11 @@ namespace FreeSql.Internal
return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
} }
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
if (tsc.getSelectGroupingMapString != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`")) if (tsc.grouping != null && expStack.First().Type.FullName.StartsWith("FreeSql.ISelectGroupingAggregate`"))
{ {
if (tsc.getSelectGroupingMapString != null) if (tsc.grouping != null)
{ {
var expText = tsc.getSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray()); var expText = tsc.grouping.GetSelectGroupingMapString(expStack.Where((a, b) => b >= 2).ToArray());
if (string.IsNullOrEmpty(expText) == false) return expText; if (string.IsNullOrEmpty(expText) == false) return expText;
} }
} }
@ -1281,9 +1287,9 @@ namespace FreeSql.Internal
if (find.Type == SelectTableInfoType.InnerJoin || if (find.Type == SelectTableInfoType.InnerJoin ||
find.Type == SelectTableInfoType.LeftJoin || find.Type == SelectTableInfoType.LeftJoin ||
find.Type == SelectTableInfoType.RightJoin) find.Type == SelectTableInfoType.RightJoin)
find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); find.On = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type));
else else
find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(null, null, find.Type)); find.NavigateCondition = ExpressionLambdaToSql(navCondExp, tsc.CloneSetselectColumnMapAndgroupingAndtbtype(null, null, find.Type));
} }
} }
} }
@ -1429,7 +1435,7 @@ namespace FreeSql.Internal
{ {
public List<SelectTableInfo> _tables { get; set; } public List<SelectTableInfo> _tables { get; set; }
public List<SelectColumnInfo> _selectColumnMap { get; set; } public List<SelectColumnInfo> _selectColumnMap { get; set; }
public Func<Expression[], string> getSelectGroupingMapString { get; set; } public SelectGroupingProvider grouping { get; set; }
public SelectTableInfoType tbtype { get; set; } public SelectTableInfoType tbtype { get; set; }
public bool isQuoteName { get; set; } public bool isQuoteName { get; set; }
public bool isDisableDiyParse { get; set; } public bool isDisableDiyParse { get; set; }
@ -1469,13 +1475,13 @@ namespace FreeSql.Internal
return old; return old;
} }
public ExpTSC CloneSetgetSelectGroupingMapStringAndgetSelectGroupingMapStringAndtbtype(List<SelectColumnInfo> v1, Func<Expression[], string> v2, SelectTableInfoType v3) public ExpTSC CloneSetselectColumnMapAndgroupingAndtbtype(List<SelectColumnInfo> v1, SelectGroupingProvider v2, SelectTableInfoType v3)
{ {
return new ExpTSC return new ExpTSC
{ {
_tables = this._tables, _tables = this._tables,
_selectColumnMap = v1, _selectColumnMap = v1,
getSelectGroupingMapString = v2, grouping = v2,
tbtype = v3, tbtype = v3,
isQuoteName = this.isQuoteName, isQuoteName = this.isQuoteName,
isDisableDiyParse = this.isDisableDiyParse, isDisableDiyParse = this.isDisableDiyParse,
@ -1495,7 +1501,7 @@ namespace FreeSql.Internal
{ {
_tables = this._tables, _tables = this._tables,
_selectColumnMap = this._selectColumnMap, _selectColumnMap = this._selectColumnMap,
getSelectGroupingMapString = this.getSelectGroupingMapString, grouping = this.grouping,
tbtype = this.tbtype, tbtype = this.tbtype,
isQuoteName = this.isQuoteName, isQuoteName = this.isQuoteName,
isDisableDiyParse = true, isDisableDiyParse = true,
@ -1537,7 +1543,7 @@ namespace FreeSql.Internal
); );
var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables = var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC { _tables =
isMultitb ? new List<SelectTableInfo>(new[] { tb }) : null, isMultitb ? new List<SelectTableInfo>(new[] { tb }) : null,
_selectColumnMap = null, getSelectGroupingMapString = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias }); _selectColumnMap = null, grouping = null, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = false, style = ExpressionStyle.Where, currentTable = tb.Table, alias001 = tb.Alias });
whereSql = GetBoolString(expExp.Body, whereSql); whereSql = GetBoolString(expExp.Body, whereSql);
if (isEmpty == false) if (isEmpty == false)
sb.Append(" AND "); sb.Append(" AND ");

View File

@ -30,7 +30,7 @@ namespace FreeSql.Internal.CommonProvider
_tables = tables; _tables = tables;
} }
public string getSelectGroupingMapString(Expression[] members) public string GetSelectGroupingMapString(Expression[] members)
{ {
if (members.Any() == false) return _map.DbField; if (members.Any() == false) return _map.DbField;
var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name; var parentName = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression)?.Member.Name;
@ -90,13 +90,13 @@ namespace FreeSql.Internal.CommonProvider
public void InternalHaving(Expression exp) public void InternalHaving(Expression exp)
{ {
var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null);
var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) }); var method = _select.GetType().GetMethod("Having", new[] { typeof(string), typeof(object) });
method.Invoke(_select, new object[] { sql, null }); method.Invoke(_select, new object[] { sql, null });
} }
public void InternalOrderBy(Expression exp, bool isDescending) public void InternalOrderBy(Expression exp, bool isDescending)
{ {
var sql = _comonExp.ExpressionWhereLambda(null, exp, getSelectGroupingMapString, null, null); var sql = _comonExp.ExpressionWhereLambda(null, exp, this, null, null);
var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) }); var method = _select.GetType().GetMethod("OrderBy", new[] { typeof(string), typeof(object) });
method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null }); method.Invoke(_select, new object[] { isDescending ? $"{sql} DESC" : sql, null });
} }
@ -106,7 +106,7 @@ namespace FreeSql.Internal.CommonProvider
var field = new StringBuilder(); var field = new StringBuilder();
var index = 0; var index = 0;
_comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); _comonExp.ReadAnonymousField(null, field, map, ref index, select, this, null, false);
if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType;
var method = _select.GetType().GetMethod(isAsync ? "ToListMapReaderAsync" : "ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic); var method = _select.GetType().GetMethod(isAsync ? "ToListMapReaderAsync" : "ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic);
method = method.MakeGenericMethod(elementType); method = method.MakeGenericMethod(elementType);
@ -118,7 +118,7 @@ namespace FreeSql.Internal.CommonProvider
var field = new StringBuilder(); var field = new StringBuilder();
var index = 0; var index = 0;
_comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, this, null, false);
if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType; if (map.Childs.Any() == false && map.MapType == null) map.MapType = elementType;
var method = _select.GetType().GetMethod("ToListMapReaderPrivate", BindingFlags.Instance | BindingFlags.NonPublic); var method = _select.GetType().GetMethod("ToListMapReaderPrivate", BindingFlags.Instance | BindingFlags.NonPublic);
method = method.MakeGenericMethod(elementType); method = method.MakeGenericMethod(elementType);
@ -132,7 +132,7 @@ namespace FreeSql.Internal.CommonProvider
var field = new StringBuilder(); var field = new StringBuilder();
var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0; var index = fieldAlias == FieldAliasOptions.AsProperty ? CommonExpression.ReadAnonymousFieldAsCsName : 0;
_comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString, null, false); _comonExp.ReadAnonymousField(null, field, map, ref index, select, this, null, false);
var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) }); 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; return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string;
} }
@ -210,7 +210,7 @@ namespace FreeSql.Internal.CommonProvider
var field = new StringBuilder(); var field = new StringBuilder();
var index = 0; var index = 0;
_comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, getSelectGroupingMapString, null, false); _comonExp.ReadAnonymousField(null, field, map, ref index, elementSelector, this, null, false);
if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement); if (map.Childs.Any() == false && map.MapType == null) map.MapType = typeof(TElement);
var method = _select.GetType().GetMethod("ToListMapReaderPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic); var method = _select.GetType().GetMethod("ToListMapReaderPrivateAsync", BindingFlags.Instance | BindingFlags.NonPublic);
method = method.MakeGenericMethod(typeof(TElement)); method = method.MakeGenericMethod(typeof(TElement));

View File

@ -17,6 +17,20 @@ namespace FreeSql.Internal.Model
public TableInfo Table { get; set; } public TableInfo Table { get; set; }
public bool IsEntity { get; set; } public bool IsEntity { get; set; }
public bool IsDefaultCtor { get; set; } public bool IsDefaultCtor { get; set; }
public void CopyTo(ReadAnonymousTypeInfo target)
{
target.Property = Property;
target.CsName = CsName;
target.CsType = CsType;
target.MapType = MapType;
target.DbField = DbField;
target.Consturctor = Consturctor;
target.Childs = Childs;
target.Table = Table;
target.IsEntity = IsEntity;
target.IsDefaultCtor = IsDefaultCtor;
}
} }
public class ReadAnonymousTypeAfInfo public class ReadAnonymousTypeAfInfo
{ {