mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-19 04:18:16 +08:00
- 增加 lambda 表达式树解析子查询 ToList + string.Join() 产生 类似 group_concat 的效果(适配了 sqlserver/pgsql/oracle/mysql/sqlite/达梦/金仓) #405;
This commit is contained in:
@ -269,5 +269,41 @@ namespace FreeSql
|
||||
}
|
||||
public interface IGroupConcat { }
|
||||
#endregion
|
||||
|
||||
#region string.Join 反射处理,此块代卖用于反射,所以别修改定义
|
||||
public static string StringJoinSqliteGroupConcat(object column, object delimiter)
|
||||
{
|
||||
expContext.Result = $"group_concat({expContext.ParsedContent["column"]},{expContext.ParsedContent["delimiter"]})";
|
||||
return null;
|
||||
}
|
||||
public static string StringJoinPgsqlGroupConcat(object column, object delimiter)
|
||||
{
|
||||
expContext.Result = $"string_agg(({expContext.ParsedContent["column"]})::text,{expContext.ParsedContent["delimiter"]})";
|
||||
return null;
|
||||
}
|
||||
public static string StringJoinMySqlGroupConcat(object column, object delimiter)
|
||||
{
|
||||
expContext.Result = $"group_concat({expContext.ParsedContent["column"]} separator {expContext.ParsedContent["delimiter"]})";
|
||||
return null;
|
||||
}
|
||||
public static string StringJoinOracleGroupConcat(object column, object delimiter)
|
||||
{
|
||||
string orderby = null;
|
||||
var subSelect = expContext._tsc?.subSelect001;
|
||||
if (subSelect != null)
|
||||
{
|
||||
orderby = subSelect?._orderby?.Trim('\r', '\n');
|
||||
if (string.IsNullOrEmpty(orderby))
|
||||
{
|
||||
var subSelectTb1 = subSelect._tables.FirstOrDefault();
|
||||
if (subSelectTb1 != null && subSelectTb1.Table.Primarys.Any() == true)
|
||||
orderby = $"order by {string.Join(",", subSelectTb1.Table.Primarys.Select(a => $"{subSelectTb1.Alias}.{subSelect._commonUtils.QuoteSqlName(a.Attribute.Name)}"))}";
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(orderby)) orderby = "order by 1";
|
||||
expContext.Result = $"listagg(to_char({expContext.ParsedContent["column"]}),{expContext.ParsedContent["delimiter"]}) within group({orderby})";
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -234,23 +234,28 @@ namespace System.Linq.Expressions
|
||||
return test.Result;
|
||||
}
|
||||
|
||||
public static bool IsStringJoin(this MethodCallExpression exp, out MethodCallExpression joinExpArgs1Out, out LambdaExpression joinExpArgs1Args0Out)
|
||||
static ConcurrentDictionary<Type, ConcurrentDictionary<string, MethodInfo>> _dicTypeMethod = new ConcurrentDictionary<Type, ConcurrentDictionary<string, MethodInfo>>();
|
||||
public static bool IsStringJoin(this MethodCallExpression exp, out Expression tolistObjectExpOut, out MethodInfo toListMethodOut, out LambdaExpression toListArgs0Out)
|
||||
{
|
||||
if (exp.Arguments.Count == 2 &&
|
||||
exp.Arguments[1].NodeType == ExpressionType.Call &&
|
||||
exp.Arguments[1].Type.FullName.StartsWith("System.Collections.Generic.List`1") &&
|
||||
exp.Arguments[1] is MethodCallExpression joinExpArgs1 &&
|
||||
joinExpArgs1.Method.Name == "ToList" &&
|
||||
joinExpArgs1.Arguments.Count == 1 &&
|
||||
joinExpArgs1.Arguments[0] is UnaryExpression joinExpArgs1Args0Tmp &&
|
||||
joinExpArgs1Args0Tmp.Operand is LambdaExpression joinExpArgs1Args0)
|
||||
exp.Arguments[1] is MethodCallExpression toListMethod &&
|
||||
toListMethod.Method.Name == "ToList" &&
|
||||
toListMethod.Arguments.Count == 1 &&
|
||||
toListMethod.Arguments[0] is UnaryExpression joinExpArgs1Args0Tmp &&
|
||||
joinExpArgs1Args0Tmp.Operand is LambdaExpression toListArgs0)
|
||||
{
|
||||
joinExpArgs1Out = joinExpArgs1;
|
||||
joinExpArgs1Args0Out = joinExpArgs1Args0;
|
||||
tolistObjectExpOut = toListMethod.Object;
|
||||
toListMethodOut = toListMethod.Type.GetGenericArguments().FirstOrDefault() == typeof(string) ?
|
||||
toListMethod.Method :
|
||||
toListMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(typeof(string));
|
||||
toListArgs0Out = toListArgs0;
|
||||
return true;
|
||||
}
|
||||
joinExpArgs1Out = null;
|
||||
joinExpArgs1Args0Out = null;
|
||||
tolistObjectExpOut = null;
|
||||
toListMethodOut = null;
|
||||
toListArgs0Out = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user