diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs index 9ebf65b3..2b64b531 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.MySqlConnector/MySqlConnector/MySqlConnectorExpression/StringTest.cs @@ -52,6 +52,36 @@ namespace FreeSql.Tests.MySqlConnectorExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs index 4dfa9e9d..a375a82a 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.dameng; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs index faa481b1..adc32074 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/KingbaseES/KingbaseESExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.KingbaseESExpression list.Add(g.kingbaseES.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.kingbaseES; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs index 61b5db83..d5488cc4 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,36 @@ namespace FreeSql.Tests.Odbc.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs index d5d4cdee..30346e3b 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs index 4105eea9..f5073512 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.Odbc.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs index 82a5d84d..48644371 100644 --- a/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests.Provider.Odbc/SqlServer/SqlServerExpression/StringTest.cs @@ -51,6 +51,36 @@ namespace FreeSql.Tests.Odbc.SqlServerExpression list.Add(g.sqlserver.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlserver; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs index 139555bc..49d61bd8 100644 --- a/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Dameng/DamengExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.DamengExpression list.Add(g.dameng.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.dameng; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs index bafb962a..3a3ab212 100644 --- a/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/MySql/MySqlExpression/StringTest.cs @@ -52,6 +52,36 @@ namespace FreeSql.Tests.MySqlExpression list.Add(g.mysql.Select().Where(a => a.IsDeleted.Equals(false)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.mysql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs index aff45a18..c15b5cae 100644 --- a/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Oracle/OracleExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.OracleExpression list.Add(g.oracle.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.oracle; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs index 4b0b9fea..341d8aa7 100644 --- a/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/PostgreSQL/PostgreSQLExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.PostgreSQLExpression list.Add(g.pgsql.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.pgsql; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs index b094b06c..ad7714d9 100644 --- a/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/SqlServer/SqlServerExpression/StringTest.cs @@ -73,9 +73,21 @@ namespace FreeSql.Tests.SqlServerExpression fsql.Delete().Where("1=1").ExecuteAffrows(); fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); - var val1 = string.Join(",", fsql.Select().ToList(a => a.name)) + ","; + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); } class StringJoin01 { diff --git a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs index 9bb2a1e7..e1c2e382 100644 --- a/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/Sqlite/SqliteExpression/StringTest.cs @@ -50,6 +50,36 @@ namespace FreeSql.Tests.SqliteExpression list.Add(g.sqlite.Select().Where(a => a.id.Equals(Guid.Empty)).ToList()); } + [Fact] + public void StringJoin() + { + var fsql = g.sqlite; + fsql.Delete().Where("1=1").ExecuteAffrows(); + fsql.Insert(new[] { new StringJoin01 { name = "北京" }, new StringJoin01 { name = "上海" }, new StringJoin01 { name = "深圳" }, }).ExecuteAffrows(); + + var val1 = string.Join(",", fsql.Select().ToList(a => a.name)); + var val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.name)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().As("b").ToList(b => b.name))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join(",", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join(",", fsql.Select().As("b").ToList(b => b.id))); + Assert.Equal(val1, val2[0]); + + val1 = string.Join("**", fsql.Select().ToList(a => a.id)); + val2 = fsql.Select().ToList(a => string.Join("**", fsql.Select().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() { diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index b3785bbb..d8903744 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -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 } } \ No newline at end of file diff --git a/FreeSql/Extensions/LambadaExpressionExtensions.cs b/FreeSql/Extensions/LambadaExpressionExtensions.cs index 203010a9..3ed0f207 100644 --- a/FreeSql/Extensions/LambadaExpressionExtensions.cs +++ b/FreeSql/Extensions/LambadaExpressionExtensions.cs @@ -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> _dicTypeMethod = new ConcurrentDictionary>(); + 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; } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index bde37cf0..ea460a59 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -794,6 +794,14 @@ + + + PostgreSQL string_agg(.., ..) + + + + + 浣跨敤杩炴帴涓诧紙鎺ㄨ崘锛 diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 85cdb639..01004c01 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -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 _tables { get; set; } public List _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, diff --git a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs index 669d2bc5..acc956e9 100644 --- a/Providers/FreeSql.Provider.Dameng/DamengExpression.cs +++ b/Providers/FreeSql.Provider.Dameng/DamengExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Dameng //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs index 7968d10e..d54733b2 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlExpression.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlExpression.cs @@ -267,6 +267,20 @@ namespace FreeSql.MySql //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs index 439dbd20..f7a344e3 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Odbc.Dameng //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 12be160a..f819d74e 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -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 diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs index af5ed688..0867c078 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlExpression.cs @@ -265,6 +265,20 @@ namespace FreeSql.Odbc.MySql //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs index 21ac435c..7ee2af4a 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Odbc.Oracle //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index cf939b59..d4fc852d 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -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 diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs index 76f2ae6d..65e0779d 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerExpression.cs @@ -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 diff --git a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs index 3daf210d..0d483ca3 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleExpression.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleExpression.cs @@ -268,6 +268,20 @@ namespace FreeSql.Oracle //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 99b46cb3..f584472c 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -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 diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index b8c3d179..aedaa4eb 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -315,6 +315,20 @@ namespace FreeSql.ShenTong //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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 diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs index f59a05f0..91ead6ed 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerExpression.cs @@ -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; } } diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs index 14280137..fa3c394a 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteExpression.cs @@ -264,6 +264,20 @@ namespace FreeSql.Sqlite //4涓 {} 鏃讹紝Arguments[1] 鍙兘瑙f瀽杩欎釜鍑烘潵锛岀劧鍚庨噷闈㈡槸 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