From ebd9cbed0f41da8c487c2c0303165e6c790623dd Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 21 Dec 2023 17:06:16 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BF=AE=E5=A4=8D=20ClickHouse=20=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E7=B1=BB=E5=9E=8B=20hasAny=20=E4=B8=8E=20In=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=86=B2=E7=AA=81=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?#1699?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Entities/User.cs | 1 + Examples/base_entity/Program.cs | 10 ++++++- Examples/base_entity/base_entity.csproj | 1 + .../ClickHouseExpression.cs | 28 +++++++++++-------- .../PostgreSQL/CustomPostgreSQLExpression.cs | 8 +++--- .../KingbaseESExpression.cs | 16 +++++------ .../KingbaseES/OdbcKingbaseESExpression.cs | 16 +++++------ .../PostgreSQL/OdbcPostgreSQLExpression.cs | 16 +++++------ .../PostgreSQLExpression.cs | 16 +++++------ .../ShenTongExpression.cs | 16 +++++------ 10 files changed, 72 insertions(+), 56 deletions(-) diff --git a/Examples/base_entity/Entities/User.cs b/Examples/base_entity/Entities/User.cs index a2bd75caf..58eca3ed7 100644 --- a/Examples/base_entity/Entities/User.cs +++ b/Examples/base_entity/Entities/User.cs @@ -42,6 +42,7 @@ public class User1 : BaseEntity public int GroupId { get; set; } public UserGroup Group { get; set; } + public string[] Tags { get; set; } public virtual List Roles { get; set; } /// diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 55b02f423..7906b3553 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -568,7 +568,7 @@ static void Main(string[] args) //.UseConnectionString(FreeSql.DataType.Firebird, @"database=localhost:D:\fbdata\EXAMPLES.fdb;user=sysdba;password=123456;max pool size=5") //.UseQuoteSqlName(false) - .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=3;AllowLoadLocalInfile=true") + // .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;min pool size=1;Max pool size=3;AllowLoadLocalInfile=true") .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=freesqlTest;Pooling=true;Max Pool Size=3;TrustServerCertificate=true") //.UseAdoConnectionPool(false) @@ -596,6 +596,7 @@ static void Main(string[] args) //.UseConnectionString(DataType.QuestDb, "host=localhost;port=8812;username=admin;password=quest;database=qdb;ServerCompatibilityMode=NoTypeLoading;") //.UseConnectionString(DataType.ClickHouse, "DataCompress=False;BufferSize=32768;SocketTimeout=10000;CheckCompressedHash=False;Encrypt=False;Compressor=lz4;Host=192.168.0.121;Port=8125;Database=PersonnelLocation;Username=root;Password=123") + .UseConnectionFactory(DataType.ClickHouse, () => null) .UseMonitorCommand(cmd => { Console.WriteLine(cmd.CommandText + "\r\n"); @@ -609,6 +610,13 @@ static void Main(string[] args) BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + var clickhouseSql1 = fsql.Select().Where(a => new[] { 1, 2, 3 }.Contains(a.GroupId)).ToSql(); + var clickhouseVal1 = new[] { 1, 2, 3 }; + var clickhouseSql2 = fsql.Select().Where(a => clickhouseVal1.Contains(a.GroupId)).ToSql(); + var clickhouseSql3 = fsql.Select().Where(a => a.Tags.Contains("tag1")).ToSql(); + var clickhouseVal2 = "tag2"; + var clickhouseSql4 = fsql.Select().Where(a => a.Tags.Contains(clickhouseVal2)).ToSql(); + fsql.Update() .Where(t => t.GroupId == 1) .ExecuteUpdated(); diff --git a/Examples/base_entity/base_entity.csproj b/Examples/base_entity/base_entity.csproj index ce19aa705..9dc7e296a 100644 --- a/Examples/base_entity/base_entity.csproj +++ b/Examples/base_entity/base_entity.csproj @@ -28,6 +28,7 @@ + diff --git a/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs b/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs index 5f72b6d14..64a24a3c4 100644 --- a/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs +++ b/Providers/FreeSql.Provider.ClickHouse/ClickHouseExpression.cs @@ -152,17 +152,23 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; return $"(case when {left} is null then 0 else length({left}) end > 0)"; case "Contains": - tsc.SetMapColumnTmp(null); - var args1 = getExp(callExp.Arguments[argIndex]); - var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); - var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug - tsc.isNotSetMapColumnTmp = true; - left = objExp == null ? null : getExp(objExp); - tsc.isNotSetMapColumnTmp = false; - tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); - if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); - if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; - return $"(hasAny({left}, [{args1}]))"; + tsc.SetMapColumnTmp(null); + var args1 = getExp(callExp.Arguments[argIndex]); + var oldMapType = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp); + var oldDbParams = objExp?.NodeType == ExpressionType.MemberAccess ? tsc.SetDbParamsReturnOld(null) : null; //#900 UseGenerateCommandParameterWithLambda(true) 子查询 bug、以及 #1173 参数化 bug + tsc.isNotSetMapColumnTmp = true; + left = objExp == null ? null : getExp(objExp); + tsc.isNotSetMapColumnTmp = false; + tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); + if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); + //判断 in 或 hasAny + if (left.StartsWith("array[") && left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"[{args1}]"; + return $"(hasAny({left}, {args1}))"; case "Concat": left = objExp == null ? null : getExp(objExp); if (left.StartsWith("(") || left.EndsWith(")")) left = $"array[{left.TrimStart('(').TrimEnd(')')}]"; diff --git a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs index df242034e..2af3ba6ef 100644 --- a/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Custom/PostgreSQL/CustomPostgreSQLExpression.cs @@ -166,12 +166,12 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) + if (left.StartsWith("array[") && left.EndsWith("]")) return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"array[{args1}]"; if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); diff --git a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs index f105376ce..1f121e3f1 100644 --- a/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.KingbaseES/KingbaseESExpression.cs @@ -165,14 +165,14 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) tsc.isNotSetMapColumnTmp = false; tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); - //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 - return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; - if (objExp != null) + //判断 in 或 array @> array + if (left.StartsWith("array[") && left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"array[{args1}]"; + if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; diff --git a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs index 91a541fe1..41e97391f 100644 --- a/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/KingbaseES/OdbcKingbaseESExpression.cs @@ -165,14 +165,14 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) tsc.isNotSetMapColumnTmp = false; tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); - //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 - return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; - if (objExp != null) + //判断 in 或 array @> array + if (left.StartsWith("array[") && left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"array[{args1}]"; + if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs index 50147da1f..086f9ff8f 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLExpression.cs @@ -165,14 +165,14 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) tsc.isNotSetMapColumnTmp = false; tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); - //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 - return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; - if (objExp != null) + //判断 in 或 array @> array + if (left.StartsWith("array[") && left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"array[{args1}]"; + if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs index 6b5e52876..f3d28da35 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLExpression.cs @@ -196,14 +196,14 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) tsc.isNotSetMapColumnTmp = false; tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); - //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 - return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; - if (objExp != null) + //判断 in 或 array @> array + if (left.StartsWith("array[") && left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"array[{args1}]"; + if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}"; diff --git a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs index d4f4ed25e..2bd58df38 100644 --- a/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs +++ b/Providers/FreeSql.Provider.ShenTong/ShenTongExpression.cs @@ -147,14 +147,14 @@ public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc) tsc.isNotSetMapColumnTmp = false; tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType); if (oldDbParams != null) tsc.SetDbParamsReturnOld(oldDbParams); - //判断 in 或 array @> array - if (left.StartsWith("array[") || left.EndsWith("]")) - return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; - if (left.StartsWith("(") || left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 - return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; - if (args1.StartsWith("(") || args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; - args1 = $"array[{args1}]"; - if (objExp != null) + //判断 in 或 array @> array + if (left.StartsWith("array[") && left.EndsWith("]")) + return $"({args1}) in ({left.Substring(6, left.Length - 7)})"; + if (left.StartsWith("(") && left.EndsWith(")")) //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格 + return $"(({args1}) in {left.Replace(", \r\n \r\n", $") \r\n OR ({args1}) in (")})"; + if (args1.StartsWith("(") && args1.EndsWith(")")) args1 = $"array[{args1.TrimStart('(').TrimEnd(')')}]"; + else args1 = $"array[{args1}]"; + if (objExp != null) { var dbinfo = _common._orm.CodeFirst.GetDbInfo(objExp.Type); if (dbinfo != null) args1 = $"{args1}::{dbinfo.dbtype}";