- 增加 lambda 表达式树解析子查询 ToList + string.Join() 产生 类似 group_concat 的效果(适配了 sqlserver/pgsql/oracle/mysql/sqlite/达梦/金仓) #405;

This commit is contained in:
28810 2020-08-08 16:18:10 +08:00
parent 1a8c7ce86d
commit b3ec6cdf8d
30 changed files with 614 additions and 17 deletions

View File

@ -52,6 +52,36 @@ namespace FreeSql.Tests.MySqlConnectorExpression
list.Add(g.mysql.Select<TestEqualsGuid>().Where(a => a.IsDeleted.Equals(false)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.mysql;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.DamengExpression
list.Add(g.dameng.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.dameng;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression
list.Add(g.kingbaseES.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.kingbaseES;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -52,6 +52,36 @@ namespace FreeSql.Tests.Odbc.MySqlExpression
list.Add(g.mysql.Select<TestEqualsGuid>().Where(a => a.IsDeleted.Equals(false)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.mysql;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.OracleExpression
list.Add(g.oracle.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.oracle;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression
list.Add(g.pgsql.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.pgsql;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -51,6 +51,36 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression
list.Add(g.sqlserver.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.DamengExpression
list.Add(g.dameng.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.dameng;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -52,6 +52,36 @@ namespace FreeSql.Tests.MySqlExpression
list.Add(g.mysql.Select<TestEqualsGuid>().Where(a => a.IsDeleted.Equals(false)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.mysql;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.OracleExpression
list.Add(g.oracle.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.oracle;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.PostgreSQLExpression
list.Add(g.pgsql.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.pgsql;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -73,9 +73,21 @@ namespace FreeSql.Tests.SqlServerExpression
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 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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{

View File

@ -50,6 +50,36 @@ namespace FreeSql.Tests.SqliteExpression
list.Add(g.sqlite.Select<TestEqualsGuid>().Where(a => a.id.Equals(Guid.Empty)).ToList());
}
[Fact]
public void StringJoin()
{
var fsql = g.sqlite;
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]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.name));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.name)));
Assert.Equal(val1, val2[0]);
val1 = string.Join(",", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join(",", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
val1 = string.Join("**", fsql.Select<StringJoin01>().ToList(a => a.id));
val2 = fsql.Select<StringJoin01>().ToList(a => string.Join("**", fsql.Select<StringJoin01>().As("b").ToList(b => b.id)));
Assert.Equal(val1, val2[0]);
}
class StringJoin01
{
[Column(IsIdentity = true)]
public int id { get; set; }
public string name { get; set; }
}
[Fact]
public void First()
{

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -794,6 +794,14 @@
<param name="column"></param>
<returns></returns>
</member>
<member name="M:FreeSql.SqlExt.StringAgg(System.Object,System.Object)">
<summary>
PostgreSQL string_agg(.., ..)
</summary>
<param name="column"></param>
<param name="delimiter"></param>
<returns></returns>
</member>
<member name="M:FreeSql.FreeSqlBuilder.UseConnectionString(FreeSql.DataType,System.String,System.Type)">
<summary>
使用连接串(推荐)

View File

@ -1060,6 +1060,7 @@ namespace FreeSql.Internal
case "Max":
case "Avg":
var tscClone1 = tsc.CloneDisableDiyParse();
tscClone1.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..)
tscClone1.isDisableDiyParse = false;
tscClone1._tables = fsqltables;
var sqlSum = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { $"{exp3.Method.Name.ToLower()}({ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone1)})" })?.ToString();
@ -1070,6 +1071,7 @@ namespace FreeSql.Internal
case "ToOne":
case "First":
var tscClone2 = tsc.CloneDisableDiyParse();
tscClone2.subSelect001 = fsql as Select0Provider; //#405 Oracle within group(order by ..)
tscClone2.isDisableDiyParse = false;
tscClone2._tables = fsqltables;
var sqlFirst = fsqlType.GetMethod("ToSql", new Type[] { typeof(string) })?.Invoke(fsql, new object[] { ExpressionLambdaToSql(exp3.Arguments.FirstOrDefault(), tscClone2) })?.ToString();
@ -1443,6 +1445,7 @@ namespace FreeSql.Internal
public List<SelectTableInfo> _tables { get; set; }
public List<SelectColumnInfo> _selectColumnMap { get; set; }
public SelectGroupingProvider grouping { get; set; }
public Select0Provider subSelect001 { get; set; } //#405 Oracle within group(order by ..)
public SelectTableInfoType tbtype { get; set; }
public bool isQuoteName { get; set; }
public bool isDisableDiyParse { get; set; }
@ -1509,6 +1512,7 @@ namespace FreeSql.Internal
_tables = this._tables,
_selectColumnMap = this._selectColumnMap,
grouping = this.grouping,
subSelect001 = this.subSelect001,
tbtype = this.tbtype,
isQuoteName = this.isQuoteName,
isDisableDiyParse = true,

View File

@ -268,6 +268,20 @@ namespace FreeSql.Dameng
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -267,6 +267,20 @@ namespace FreeSql.MySql
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray();
return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})";
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinMySqlGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -268,6 +268,20 @@ namespace FreeSql.Odbc.Dameng
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -337,6 +337,20 @@ namespace FreeSql.Odbc.KingbaseES
return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'";
}).ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -265,6 +265,20 @@ namespace FreeSql.Odbc.MySql
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"',{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")},'").ToArray();
return $"concat({string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs)})";
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinMySqlGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -268,6 +268,20 @@ namespace FreeSql.Odbc.Oracle
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -359,6 +359,20 @@ namespace FreeSql.Odbc.PostgreSQL
return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'";
}).ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -284,6 +284,24 @@ namespace FreeSql.Odbc.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 tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),
Expression.Convert(exp.Arguments[0], typeof(object)),
Expression.Convert(toListArgs1.Body, typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")"))
{
newToListSql = $"stuff({newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH('')),1,len({getExp(exp.Arguments[0])}),'')";
return newToListSql;
}
}
break;
}
}
else

View File

@ -268,6 +268,20 @@ namespace FreeSql.Oracle
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -390,6 +390,20 @@ namespace FreeSql.PostgreSQL
return $"'||{_common.IsNull($"({ExpressionLambdaToSql(a, tsc)})::text", "''")}||'";
}).ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinPgsqlGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -315,6 +315,20 @@ namespace FreeSql.ShenTong
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join": //未通用测试 #405
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinOracleGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else

View File

@ -284,19 +284,19 @@ namespace FreeSql.SqlServer
}).ToArray();
return string.Format(expArgs0, expArgs);
case "Join":
if (exp.IsStringJoin(out var joinExpArgs1, out var joinExpArgs1Args0))
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(joinExpArgs1.Object, joinExpArgs1.Method,
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
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));
Expression.Convert(exp.Arguments[0], typeof(object)),
Expression.Convert(toListArgs1.Body, typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
if (string.IsNullOrEmpty(newToListSql) == false && newToListSql.StartsWith("(") && newToListSql.EndsWith(")"))
{
newToListSql = $"{newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH(''))";
newToListSql = $"stuff({newToListSql.Substring(0, newToListSql.Length - 1)} FOR XML PATH('')),1,len({getExp(exp.Arguments[0])}),'')";
return newToListSql;
}
}

View File

@ -264,6 +264,20 @@ namespace FreeSql.Sqlite
//4个 {} 时Arguments[1] 只能解析这个出来,然后里面是 NewArray []
var expArgs = expArgsHack.Select(a => $"'||{_common.IsNull(ExpressionLambdaToSql(a, tsc), "''")}||'").ToArray();
return string.Format(ExpressionLambdaToSql(exp.Arguments[0], tsc), expArgs);
case "Join":
if (exp.IsStringJoin(out var tolistObjectExp, out var toListMethod, out var toListArgs1))
{
var newToListArgs0 = Expression.Call(tolistObjectExp, toListMethod,
Expression.Lambda(
Expression.Call(
typeof(SqlExtExtensions).GetMethod("StringJoinSqliteGroupConcat"),
Expression.Convert(toListArgs1.Body, typeof(object)),
Expression.Convert(exp.Arguments[0], typeof(object))),
toListArgs1.Parameters));
var newToListSql = getExp(newToListArgs0);
return newToListSql;
}
break;
}
}
else