From 322332cf73ae8e76a1fd49fb39a3ea4359812f78 Mon Sep 17 00:00:00 2001 From: d4ilys <963922242@qq.com> Date: Tue, 21 Nov 2023 11:20:54 +0800 Subject: [PATCH] =?UTF-8?q?Clickhouse=20Array=E6=B3=9B=E5=9E=8B=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E5=8A=9F=E8=83=BD=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ClickHouse/ClickHouseTest3.cs | 33 +++++++- FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml | 5 ++ .../ClickHouseCodeFirst.cs | 84 +++++++++++++++---- 3 files changed, 106 insertions(+), 16 deletions(-) diff --git a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest3.cs b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest3.cs index ecad96a1..953eef71 100644 --- a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickHouseTest3.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -20,7 +21,7 @@ namespace FreeSql.Tests.ClickHouse _fsql = new FreeSqlBuilder().UseConnectionString(DataType.ClickHouse, "Host=192.168.1.123;Port=8123;Database=test;Compress=True;Min Pool Size=1") .UseMonitorCommand(cmd => _output.WriteLine($"线程:{cmd.CommandText}\r\n")) - .UseNoneCommandParameter(false) + .UseNoneCommandParameter(true) .Build(); } @@ -106,6 +107,15 @@ namespace FreeSql.Tests.ClickHouse { var list = _fsql.Select().ToList(); } + + /// + /// 测试Array类型映射 + /// + [Fact] + public void ArrayBoolMappingSync() + { + _fsql.CodeFirst.SyncStructure(typeof(ArrayMappingTest)); + } } [Table(Name = "table_test_bool")] @@ -122,4 +132,25 @@ namespace FreeSql.Tests.ClickHouse [Column(Name = "is_enable")] public bool? IsEnable { get; set; } } + + [Table(Name = "table_test_array")] + public class ArrayMappingTest + { + [Column(Name = "name", IsPrimary = true)] + public string Name { get; set; } + + [Column(Name = "tags1")] public IEnumerable Tags1 { get; set; } + + [Column(Name = "tags2")] public IList Tags2 { get; set; } + + [Column(Name = "tags3")] public List Tags3 { get; set; } + + [Column(Name = "tags4")] public ArrayList Tags4 { get; set; } + + [Column(Name = "tags5")] public Array Tags5 { get; set; } + + [Column(Name = "tags6")] public List Tags6 { get; set; } + + [Column(Name = "tags7")] public IEnumerable Tags7 { get; set; } + } } \ No newline at end of file diff --git a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml index 5f6bcd3a..5f515a4c 100644 --- a/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml +++ b/FreeSql.Tests/FreeSql.Tests/FreeSql.Tests.xml @@ -29,6 +29,11 @@ 测试bool类型查询 + + + 测试Array类型映射 + + 实时数据 diff --git a/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs b/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs index 38763de3..c1296886 100644 --- a/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs +++ b/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs @@ -1,6 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; using System; +using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; @@ -50,7 +51,8 @@ namespace FreeSql.ClickHouse { typeof(float?).FullName, CsToDb.New(DbType.Single, "Float32", "Nullable(Float32)", false, true, null) }, { typeof(decimal).FullName, - CsToDb.New(DbType.Decimal, "Decimal(38, 19)", "Decimal(38, 19)", false, false, 0) //Nullable(Decimal(38, 19)) + CsToDb.New(DbType.Decimal, "Decimal(38, 19)", "Decimal(38, 19)", false, false, + 0) //Nullable(Decimal(38, 19)) }, { typeof(decimal?).FullName, @@ -75,16 +77,68 @@ namespace FreeSql.ClickHouse { typeof(Guid?).FullName, CsToDb.New(DbType.String, "String", "Nullable(String)", false, true, null) }, }; + public override DbInfoResult GetDbInfo(Type type) { if (_dicCsToDb.TryGetValue(type.FullName, out var trydc)) return new DbInfoResult((int)trydc.type, trydc.dbtype, trydc.dbtypeFull, trydc.isnullable, trydc.defaultValue); - if (type.IsArray) - return null; + + //判断是否是集合 + var isCollection = IsCollection(type); + if (isCollection.Item1) + { + var genericType = isCollection.Item2; + var genericTypeName = genericType?.FullName; + var tryGetValue = _dicCsToDb.TryGetValue(genericTypeName, out var value); + if (tryGetValue) + { + var arrayDbType = $"Array({value.dbtype})"; + var defaultArray = new ArrayList(0); + return new DbInfoResult(Convert.ToInt32(DbType.Object), arrayDbType, arrayDbType, false,defaultArray); + } + + } return null; } + private Tuple IsCollection(Type type) + { + var flag = false; + Type resultType = null; + var interfaces = type.GetInterfaces(); + + if (interfaces.Any(t => t.Name == "IList")) + flag = true; + + if (interfaces.Any(t => t.Name == "ICollection")) + flag = true; + + if (interfaces.Any(t => t.Name == "IEnumerable")) + flag = true; + + if (type.Name == "Array") + { + flag = true; + resultType = typeof(string); + } + + if (type.Name == "ArrayList") + { + flag = true; + resultType = typeof(string); + } + + //是否是泛型 + if (type.GetGenericArguments().Any()) + { + var first = type.GetGenericArguments().First(); + resultType = first; + } + + return new Tuple(flag, resultType); + } + protected override string GetComparisonDDLStatements(params TypeAndName[] objects) { Object conn = null; @@ -299,7 +353,8 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); //添加列 sbalter.Append("ALTER TABLE ").Append(_commonUtils.QuoteSqlName(tbname[0], tbname[1])) - .Append(" ADD Column ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)).Append(" ") + .Append(" ADD Column ").Append(_commonUtils.QuoteSqlName(tbcol.Attribute.Name)) + .Append(" ") .Append(tbcol.Attribute.DbType); if (tbcol.Attribute.IsNullable == false && tbcol.DbDefaultValue != "NULL" && tbcol.Attribute.IsIdentity == false) @@ -483,7 +538,7 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); cmd.CommandText = sql; cmd.CommandType = CommandType.Text; var before = new Aop.CommandBeforeEventArgs(cmd); - this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before); + this._orm?.Aop.CommandBeforeHandler?.Invoke(this._orm, before); Exception afterException = null; try { @@ -496,7 +551,8 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); } finally { - this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, new Aop.CommandAfterEventArgs(before, afterException, null)); + this._orm?.Aop.CommandAfterHandler?.Invoke(this._orm, + new Aop.CommandAfterEventArgs(before, afterException, null)); } } } @@ -511,12 +567,13 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); { if (isPrimary) { - if (dbType.Contains("Nullable")) + if (dbType.Contains("Nullable")) return dbType.Replace("Nullable(", "") .Replace(")", "") .Replace(" NOT NULL", ""); return dbType; } + return dbType.Replace(" NOT NULL", ""); } @@ -524,6 +581,9 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); string CkIntAdapter(string dbType) { var result = dbType; + if (dbType.Contains("Array")) + return dbType; + if (dbType.ToLower().Contains("int64")) { if (dbType.Contains("Nullable")) @@ -578,13 +638,7 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); internal class ClickHouseTableIndex { - public string name - { - get; set; - } - public string expr - { - get; set; - } + public string name { get; set; } + public string expr { get; set; } } } \ No newline at end of file