mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-04-22 18:52:50 +08:00
- 增加 SqlServer lambda 表达式树解析子查询 ToList + string.Join() 产生 类似 group_concat 的效果;#405
This commit is contained in:
parent
25e73117b1
commit
1a8c7ce86d
@ -66,6 +66,24 @@ namespace FreeSql.Tests.SqlServerExpression
|
||||
list.Add(select.Where(a => a.TitleVarchar == "aaa").ToList());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StringJoin()
|
||||
{
|
||||
var fsql = g.sqlserver;
|
||||
fsql.Delete<StringJoin01>().Where("1=1").ExecuteAffrows();
|
||||
fsql.Insert(new[] { new StringJoin01 { name = "±±¾©" }, new StringJoin01 { name = "ÉϺ£" }, new StringJoin01 { name = "ÉîÛÚ" }, }).ExecuteAffrows();
|
||||
|
||||
var val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.name)) + ",";
|
||||
var val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
|
||||
Assert.Equal(val1, val2[0]);
|
||||
}
|
||||
class StringJoin01
|
||||
{
|
||||
[Column(IsIdentity = true)]
|
||||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void First()
|
||||
{
|
||||
|
@ -114,6 +114,18 @@ namespace FreeSql
|
||||
/// <param name="column"></param>
|
||||
/// <returns></returns>
|
||||
public static IGroupConcat GroupConcat(object column) => SqlExtExtensions.GroupConcat(column);
|
||||
|
||||
/// <summary>
|
||||
/// PostgreSQL string_agg(.., ..)
|
||||
/// </summary>
|
||||
/// <param name="column"></param>
|
||||
/// <param name="delimiter"></param>
|
||||
/// <returns></returns>
|
||||
public static string StringAgg(object column, object delimiter)
|
||||
{
|
||||
expContext.Value.Result = $"string_agg({expContext.Value.ParsedContent["column"]}, {expContext.Value.ParsedContent["delimiter"]})";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
[ExpressionCall]
|
||||
|
@ -233,6 +233,26 @@ namespace System.Linq.Expressions
|
||||
test.Visit(exp);
|
||||
return test.Result;
|
||||
}
|
||||
|
||||
public static bool IsStringJoin(this MethodCallExpression exp, out MethodCallExpression joinExpArgs1Out, out LambdaExpression joinExpArgs1Args0Out)
|
||||
{
|
||||
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)
|
||||
{
|
||||
joinExpArgs1Out = joinExpArgs1;
|
||||
joinExpArgs1Args0Out = joinExpArgs1Args0;
|
||||
return true;
|
||||
}
|
||||
joinExpArgs1Out = null;
|
||||
joinExpArgs1Args0Out = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal class NewExpressionVisitor : ExpressionVisitor
|
||||
|
@ -283,6 +283,24 @@ namespace FreeSql.SqlServer
|
||||
return $"'+{_common.IsNull($"cast({ExpressionLambdaToSql(a, tsc)} as nvarchar(max))", "''")}+{nchar}'";
|
||||
}).ToArray();
|
||||
return string.Format(expArgs0, expArgs);
|
||||
case "Join":
|
||||
if (exp.IsStringJoin(out var joinExpArgs1, out var joinExpArgs1Args0))
|
||||
{
|
||||
var newToListArgs0 = Expression.Call(joinExpArgs1.Object, joinExpArgs1.Method,
|
||||
Expression.Lambda(
|
||||
Expression.Call(
|
||||
typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),
|
||||
Expression.Convert(joinExpArgs1Args0.Body, typeof(object)),
|
||||
Expression.Convert(exp.Arguments[0], typeof(object))),
|
||||
joinExpArgs1Args0.Parameters));
|
||||
var newToListSql = getExp(newToListArgs0);
|
||||
if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")"))
|
||||
{
|
||||
newToListSql = $"{newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH(''))";
|
||||
return newToListSql;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user