This commit is contained in:
2881099 2024-02-01 14:19:34 +08:00
parent 7e897784a2
commit 1b807f3cf6
2 changed files with 21 additions and 33 deletions

View File

@ -25,8 +25,7 @@ namespace FreeSql.Internal
public ParameterExpression _lambdaParameter; public ParameterExpression _lambdaParameter;
public ReadAnonymousTypeInfo _map; public ReadAnonymousTypeInfo _map;
public string _field; public string _field;
public ReadAnonymousTypeInfo ParseExpMapResult { get; internal protected set; } public ReadAnonymousTypeInfo ParseExpMapResult { get; protected set; }
public ColumnInfo ParseExpColumnResult { get; internal protected set; }
public abstract string ParseExp(Expression[] members); public abstract string ParseExp(Expression[] members);
} }
@ -532,7 +531,7 @@ namespace FreeSql.Internal
parent.Childs.Add(child); parent.Childs.Add(child);
if (dtTb.Parameter != null) if (dtTb.Parameter != null)
ReadAnonymousField(_tables, _tableRule, field, child, ref index, Expression.Property( ReadAnonymousField(_tables, _tableRule, field, child, ref index, Expression.Property(
dtTb.Parameter.Type == dtTb.Table.Type ? (Expression)dtTb.Parameter : Expression.TypeAs(dtTb.Parameter, dtTb.Table.Type), dtTb.Parameter.Type == dtTb.Table.Type ? (Expression)dtTb.Parameter : Expression.TypeAs(dtTb.Parameter, dtTb.Table.Type),
dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap); dtTb.Table.Properties[trydtocol.CsName]), select, diymemexp, whereGlobalFilter, findIncludeMany, findSubSelectMany, isAllDtoMap);
else else
{ {
@ -825,7 +824,7 @@ namespace FreeSql.Internal
var rightBool = ExpressionLambdaToSql(rightExp, tsc); var rightBool = ExpressionLambdaToSql(rightExp, tsc);
var rightColumn = SearchColumnByField(tsc._tables, tsc.currentTable, rightBool); var rightColumn = SearchColumnByField(tsc._tables, tsc.currentTable, rightBool);
if (rightColumn != null) rightBool = $"{rightBool} = {formatSql(true, rightColumn.Attribute.MapType, null, null)}"; if (rightColumn != null) rightBool = $"{rightBool} = {formatSql(true, rightColumn.Attribute.MapType, null, null)}";
else rightBool = GetBoolString(rightBool); else rightBool = GetBoolString(rightBool);
if (_common._orm?.Ado?.DataType == DataType.QuestDb) return $"(({leftBool}) {oper} ({rightBool}))"; if (_common._orm?.Ado?.DataType == DataType.QuestDb) return $"(({leftBool}) {oper} ({rightBool}))";
return $"({leftBool} {oper} {rightBool})"; return $"({leftBool} {oper} {rightBool})";
@ -860,20 +859,17 @@ namespace FreeSql.Internal
} }
Type oldMapType = null; Type oldMapType = null;
if (tsc.diymemexp != null) tsc.diymemexp.ParseExpColumnResult = null;
var left = ExpressionLambdaToSql(leftExp, tsc); var left = ExpressionLambdaToSql(leftExp, tsc);
var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left) ?? var leftMapColumn = SearchColumnByField(tsc._tables, tsc.currentTable, left);
tsc.diymemexp?.ParseExpColumnResult; //group by emum -> MapType(string) #1727
var isLeftMapType = leftMapColumn != null && new[] { "AND", "OR", "*", "/", "+", "-" }.Contains(oper) == false && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type); var isLeftMapType = leftMapColumn != null && new[] { "AND", "OR", "*", "/", "+", "-" }.Contains(oper) == false && (leftMapColumn.Attribute.MapType != rightExp.Type || leftMapColumn.CsType != rightExp.Type);
ColumnInfo rightMapColumn = null; ColumnInfo rightMapColumn = null;
var isRightMapType = false; var isRightMapType = false;
if (isLeftMapType) oldMapType = tsc.SetMapTypeReturnOld(leftMapColumn.Attribute.MapType); if (isLeftMapType) oldMapType = tsc.SetMapTypeReturnOld(leftMapColumn.Attribute.MapType);
var right = (leftMapColumn != null && var right = (leftMapColumn != null &&
(leftMapColumn.Table.AsTableColumn == leftMapColumn && rightExp.IsParameter() == false)) ? //自动分表 (leftMapColumn.Table.AsTableColumn == leftMapColumn && rightExp.IsParameter() == false)) ? //自动分表
formatSql(Expression.Lambda(rightExp).Compile().DynamicInvoke(), leftMapColumn.Attribute.MapType, leftMapColumn, tsc.dbParams) : formatSql(Expression.Lambda(rightExp).Compile().DynamicInvoke(), leftMapColumn.Attribute.MapType, leftMapColumn, tsc.dbParams) :
ExpressionLambdaToSql(rightExp, tsc); ExpressionLambdaToSql(rightExp, tsc);
if (isLeftMapType) tsc.SetMapTypeReturnOld(leftMapColumn.Attribute.MapType);
if (right != "NULL" && isLeftMapType && if (right != "NULL" && isLeftMapType &&
//判断参数化后的bug //判断参数化后的bug
!(right.Contains('@') || right.Contains('?') || right.Contains(':')) && !(right.Contains('@') || right.Contains('?') || right.Contains(':')) &&
@ -896,11 +892,10 @@ namespace FreeSql.Internal
if (isRightMapType) if (isRightMapType)
{ {
oldMapType = tsc.SetMapTypeReturnOld(rightMapColumn.Attribute.MapType); oldMapType = tsc.SetMapTypeReturnOld(rightMapColumn.Attribute.MapType);
left = (rightMapColumn != null && left = (rightMapColumn != null &&
(rightMapColumn.Table.AsTableColumn == rightMapColumn && leftExp.IsParameter() == false)) ? //自动分表 (rightMapColumn.Table.AsTableColumn == rightMapColumn && leftExp.IsParameter() == false)) ? //自动分表
formatSql(Expression.Lambda(leftExp).Compile().DynamicInvoke(), rightMapColumn.Attribute.MapType, rightMapColumn, tsc.dbParams) : formatSql(Expression.Lambda(leftExp).Compile().DynamicInvoke(), rightMapColumn.Attribute.MapType, rightMapColumn, tsc.dbParams) :
ExpressionLambdaToSql(leftExp, tsc); ExpressionLambdaToSql(leftExp, tsc);
if (isRightMapType) tsc.SetMapTypeReturnOld(rightMapColumn.Attribute.MapType);
if (left != "NULL" && isRightMapType && if (left != "NULL" && isRightMapType &&
//判断参数化后的bug //判断参数化后的bug
!(left.Contains('@') || left.Contains('?') || left.Contains(':')) && !(left.Contains('@') || left.Contains('?') || left.Contains(':')) &&
@ -990,7 +985,7 @@ namespace FreeSql.Internal
{ {
case ExpressionType.Not: case ExpressionType.Not:
var notExp = (exp as UnaryExpression)?.Operand; var notExp = (exp as UnaryExpression)?.Operand;
if (notExp.Type.IsNumberType())return _common.BitNot(ExpressionLambdaToSql(notExp, tsc)); //位操作 if (notExp.Type.IsNumberType()) return _common.BitNot(ExpressionLambdaToSql(notExp, tsc)); //位操作
if (notExp.NodeType == ExpressionType.MemberAccess) if (notExp.NodeType == ExpressionType.MemberAccess)
{ {
var notBody = ExpressionLambdaToSql(notExp, tsc); var notBody = ExpressionLambdaToSql(notExp, tsc);
@ -1006,7 +1001,7 @@ namespace FreeSql.Internal
case ExpressionType.Invoke: //#1378 case ExpressionType.Invoke: //#1378
var invokeExp = exp as InvocationExpression; var invokeExp = exp as InvocationExpression;
var invokeReplaceExp = invokeExp.Expression; var invokeReplaceExp = invokeExp.Expression;
var invokeLambdaExp = invokeReplaceExp as LambdaExpression; var invokeLambdaExp = invokeReplaceExp as LambdaExpression;
if (invokeLambdaExp == null) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams); if (invokeLambdaExp == null) return formatSql(Expression.Lambda(exp).Compile().DynamicInvoke(), tsc.mapType, tsc.mapColumnTmp, tsc.dbParams);
var invokeReplaceVistor = new FreeSql.Internal.CommonExpression.ReplaceVisitor(); var invokeReplaceVistor = new FreeSql.Internal.CommonExpression.ReplaceVisitor();
var len = Math.Min(invokeExp.Arguments.Count, invokeLambdaExp.Parameters.Count); var len = Math.Min(invokeExp.Arguments.Count, invokeLambdaExp.Parameters.Count);
@ -1842,7 +1837,7 @@ namespace FreeSql.Internal
} }
if (callExp != null) return ExpressionLambdaToSql(callExp, tsc); if (callExp != null) return ExpressionLambdaToSql(callExp, tsc);
var diymemexps = new[] { tsc.diymemexp, tsc.subSelect001?._diymemexpWithTempQuery }; var diymemexps = new[] { tsc.diymemexp, tsc.subSelect001?._diymemexpWithTempQuery };
if (_subSelectParentDiyMemExps.Value?.Any() == true) if (_subSelectParentDiyMemExps.Value?.Any() == true)
diymemexps = diymemexps.Concat(_subSelectParentDiyMemExps.Value).ToArray(); diymemexps = diymemexps.Concat(_subSelectParentDiyMemExps.Value).ToArray();
foreach (var diymemexp in diymemexps) foreach (var diymemexp in diymemexps)
{ {
@ -2425,7 +2420,7 @@ namespace FreeSql.Internal
new ReplaceParameterVisitor().Modify(fl.Where, newParameter), new ReplaceParameterVisitor().Modify(fl.Where, newParameter),
newParameter newParameter
); );
var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC var whereSql = ExpressionLambdaToSql(expExp.Body, new ExpTSC
{ {
_tables = isMultitb ? new List<SelectTableInfo>(new[] { tb }) : null, _tables = isMultitb ? new List<SelectTableInfo>(new[] { tb }) : null,
_selectColumnMap = null, _selectColumnMap = null,
@ -2507,8 +2502,8 @@ namespace FreeSql.Internal
public LambdaExpression Modify(LambdaExpression lambda, List<SelectTableInfo> tables) public LambdaExpression Modify(LambdaExpression lambda, List<SelectTableInfo> tables)
{ {
this.tables = tables.Where(a => a.Type != SelectTableInfoType.Parent).ToList(); this.tables = tables.Where(a => a.Type != SelectTableInfoType.Parent).ToList();
parameters = this.tables.Select(a => a.Parameter ?? parameters = this.tables.Select(a => a.Parameter ??
Expression.Parameter(a.Table.Type, Expression.Parameter(a.Table.Type,
a.Alias.StartsWith("SP10") ? a.Alias.Replace("SP10", "ht") : a.Alias)).ToArray(); a.Alias.StartsWith("SP10") ? a.Alias.Replace("SP10", "ht") : a.Alias)).ToArray();
lambdaHzyParameter = lambda.Parameters.FirstOrDefault(); lambdaHzyParameter = lambda.Parameters.FirstOrDefault();
var exp = Visit(lambda.Body); var exp = Visit(lambda.Body);
@ -2596,7 +2591,7 @@ namespace FreeSql.Internal
{ {
if (matchIgnores.ContainsKey(typeProp)) continue; if (matchIgnores.ContainsKey(typeProp)) continue;
matchIgnores.Add(typeProp, true); matchIgnores.Add(typeProp, true);
var nextExp = Expression.MakeMemberAccess(memExp, typeProp); var nextExp = Expression.MakeMemberAccess(memExp, typeProp);
var ret = LocalMatch(typeProp.PropertyType, nextExp); var ret = LocalMatch(typeProp.PropertyType, nextExp);
if (ret != null) if (ret != null)
{ {
@ -2765,8 +2760,8 @@ namespace FreeSql.Internal
Type = SelectTableInfoType.Parent, Type = SelectTableInfoType.Parent,
Parameter = a.Parameter Parameter = a.Parameter
})); }));
if (dbParams != null) select.WithParameters(dbParams); if (dbParams != null) select.WithParameters(dbParams);
if (tableRule != null) select._tableRules.Add(tableRule); if (tableRule != null) select._tableRules.Add(tableRule);
if (whereGlobalFilter != null) if (whereGlobalFilter != null)
{ {
select._whereGlobalFilter.Clear(); select._whereGlobalFilter.Clear();

View File

@ -36,11 +36,9 @@ namespace FreeSql.Internal.CommonProvider
public override string ParseExp(Expression[] members) public override string ParseExp(Expression[] members)
{ {
ParseExpMapResult = null; ParseExpMapResult = null;
ParseExpColumnResult = null;
if (members.Any() == false) if (members.Any() == false)
{ {
ParseExpMapResult = _map; ParseExpMapResult = _map;
ParseExpColumnResult = ParseExpMapResult.GetColumn();
return _map.DbField; return _map.DbField;
} }
var firstMember = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression); var firstMember = ((members.FirstOrDefault() as MemberExpression)?.Expression as MemberExpression);
@ -55,7 +53,6 @@ namespace FreeSql.Internal.CommonProvider
if (read == null) return null; if (read == null) return null;
} }
ParseExpMapResult = read; ParseExpMapResult = read;
ParseExpColumnResult = ParseExpMapResult.GetColumn();
if (!_addFieldAlias) return read.DbField; if (!_addFieldAlias) return read.DbField;
if (_flagNestedFieldAlias) return read.DbField; if (_flagNestedFieldAlias) return read.DbField;
if (_comonExp.EndsWithDbNestedField(read.DbField, read.DbNestedField) == false) if (_comonExp.EndsWithDbNestedField(read.DbField, read.DbNestedField) == false)
@ -85,7 +82,6 @@ namespace FreeSql.Internal.CommonProvider
members[a] = replaceVistor.Modify(members[a], replaceMember, curtable.Parameter); members[a] = replaceVistor.Modify(members[a], replaceMember, curtable.Parameter);
var ret = _select._diymemexpWithTempQuery.ParseExp(members); var ret = _select._diymemexpWithTempQuery.ParseExp(members);
ParseExpMapResult = _select._diymemexpWithTempQuery.ParseExpMapResult; ParseExpMapResult = _select._diymemexpWithTempQuery.ParseExpMapResult;
ParseExpColumnResult = ParseExpMapResult.GetColumn();
return ret; return ret;
} }
} }
@ -134,10 +130,7 @@ namespace FreeSql.Internal.CommonProvider
return null; return null;
} }
} }
var tsc = new CommonExpression.ExpTSC { _tables = _tables, _tableRule = _select._tableRule, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = true, style = CommonExpression.ExpressionStyle.Where }; return _comonExp.ExpressionLambdaToSql(retExp, new CommonExpression.ExpTSC { _tables = _tables, _tableRule = _select._tableRule, tbtype = SelectTableInfoType.From, isQuoteName = true, isDisableDiyParse = true, style = CommonExpression.ExpressionStyle.Where });
var result = _comonExp.ExpressionLambdaToSql(retExp, tsc);
ParseExpColumnResult = tsc.mapColumnTmp;
return result;
} }
return null; return null;
} }
@ -238,7 +231,7 @@ namespace FreeSql.Internal.CommonProvider
public class SelectGroupingProvider<TKey, TValue> : SelectGroupingProvider, ISelectGrouping<TKey, TValue> public class SelectGroupingProvider<TKey, TValue> : SelectGroupingProvider, ISelectGrouping<TKey, TValue>
{ {
public SelectGroupingProvider(IFreeSql orm, Select0Provider select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List<SelectTableInfo> tables) public SelectGroupingProvider(IFreeSql orm, Select0Provider select, ReadAnonymousTypeInfo map, string field, CommonExpression comonExp, List<SelectTableInfo> tables)
:base(orm, select, map, field, comonExp, tables) { } : base(orm, select, map, field, comonExp, tables) { }
public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex) public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<TKey, TValue>, TReturn>> select, FieldAliasOptions fieldAlias = FieldAliasOptions.AsIndex)
{ {
@ -262,10 +255,10 @@ namespace FreeSql.Internal.CommonProvider
Select0Provider.WithTempQueryParser parser = null; Select0Provider.WithTempQueryParser parser = null;
_addFieldAlias = true; //解决:[Column(Name = "flevel") 与属性名不一致时,嵌套查询 bug _addFieldAlias = true; //解决:[Column(Name = "flevel") 与属性名不一致时,嵌套查询 bug
_flagNestedFieldAlias = true;//解决重复设置别名问题:.GroupBy((l, p) => new { p.ID, ShopType=l.ShopType??0 }).WithTempQuery(a => new { Money = a.Sum(a.Value.Item1.Amount)* a.Key.ShopType }) _flagNestedFieldAlias = true;//解决重复设置别名问题:.GroupBy((l, p) => new { p.ID, ShopType=l.ShopType??0 }).WithTempQuery(a => new { Money = a.Sum(a.Value.Item1.Amount)* a.Key.ShopType })
var old_field = _field; var old_field = _field;
var fieldsb = new StringBuilder(); var fieldsb = new StringBuilder();
if (_map.Childs.Any() == false) fieldsb.Append(", ").Append(_map.DbField).Append(_comonExp.EndsWithDbNestedField(_map.DbField, _map.DbNestedField) ? "" : _comonExp._common.FieldAsAlias(_map.DbNestedField)); if (_map.Childs.Any() == false) fieldsb.Append(", ").Append(_map.DbField).Append(_comonExp.EndsWithDbNestedField(_map.DbField, _map.DbNestedField) ? "" : _comonExp._common.FieldAsAlias(_map.DbNestedField));
foreach (var child in _map.GetAllChilds()) foreach (var child in _map.GetAllChilds())
fieldsb.Append(", ").Append(child.DbField).Append(_comonExp.EndsWithDbNestedField(child.DbField, child.DbNestedField) ? "" : _comonExp._common.FieldAsAlias(child.DbNestedField)); fieldsb.Append(", ").Append(child.DbField).Append(_comonExp.EndsWithDbNestedField(child.DbField, child.DbNestedField) ? "" : _comonExp._common.FieldAsAlias(child.DbNestedField));
_field = fieldsb.ToString(); _field = fieldsb.ToString();
fieldsb.Clear(); fieldsb.Clear();
@ -279,7 +272,7 @@ namespace FreeSql.Internal.CommonProvider
_field = old_field; _field = old_field;
_addFieldAlias = false; _addFieldAlias = false;
_flagNestedFieldAlias = false; _flagNestedFieldAlias = false;
} }
var sql = $"\r\n{this.ToSql(parser._insideSelectList[0].InsideField)}"; var sql = $"\r\n{this.ToSql(parser._insideSelectList[0].InsideField)}";
ret.WithSql(sql); ret.WithSql(sql);
ret._diymemexpWithTempQuery = parser; ret._diymemexpWithTempQuery = parser;