From a53cbdd3db9a6490b28c8d0e1caf7711d28b86e8 Mon Sep 17 00:00:00 2001 From: Daily <963922242@qq.com> Date: Thu, 30 May 2024 14:30:08 +0800 Subject: [PATCH] =?UTF-8?q?ClickHouse=E8=A1=A8=E5=88=86=E5=8C=BA=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ClickHouse/ClickhouseIssueTest.cs | 32 +++++++++++++++ .../ClickHousePartitionAttribute.cs | 17 ++++++++ .../ClickHouseCodeFirst.cs | 40 +++++++++++++++---- 3 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 Providers/FreeSql.Provider.ClickHouse/Attributes/ClickHousePartitionAttribute.cs diff --git a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickhouseIssueTest.cs b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickhouseIssueTest.cs index cf84442a..a518aeff 100644 --- a/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickhouseIssueTest.cs +++ b/FreeSql.Tests/FreeSql.Tests/ClickHouse/ClickhouseIssueTest.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using FreeSql.DataAnnotations; +using FreeSql.Provider.ClickHouse.Attributes; using Xunit; using Xunit.Abstractions; @@ -141,10 +142,41 @@ namespace FreeSql.Tests.ClickHouse public string Name { get; set; } public int Age { get; set; } + public DateTime CreateTime { get; set; } + public DateTime? UpdateTime { get; set; } } #endregion + + #region https: //github.com/dotnetcore/FreeSql/issues/1814 + + public class Test1814Table + { + [Column(IsPrimary = true, IsIdentity = true)] + public int Id { get; set; } + + public string Name { get; set; } + + [ClickHousePartition] + [Column(Name = "create_time")] + public DateTime CreateTime { get; set; } + } + + [Fact] + public void TestIssue1814() + { + _fsql.CodeFirst.SyncStructure(); + + var insert = _fsql.Insert(new Test1814Table + { + Name = "test", + CreateTime = DateTime.Now + }).ExecuteAffrows(); + + var query = _fsql.Select().ToList(); + } + #endregion } } \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ClickHouse/Attributes/ClickHousePartitionAttribute.cs b/Providers/FreeSql.Provider.ClickHouse/Attributes/ClickHousePartitionAttribute.cs new file mode 100644 index 00000000..c19c31dd --- /dev/null +++ b/Providers/FreeSql.Provider.ClickHouse/Attributes/ClickHousePartitionAttribute.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FreeSql.Provider.ClickHouse.Attributes +{ + [AttributeUsage(AttributeTargets.Property)] + public class ClickHousePartitionAttribute : Attribute + { + public ClickHousePartitionAttribute(string format = "toYYYYMM({0})") + { + Format = format; + } + + public string Format { get; set; } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs b/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs index 15704eef..110172ee 100644 --- a/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs +++ b/Providers/FreeSql.Provider.ClickHouse/ClickHouseCodeFirst.cs @@ -8,8 +8,10 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Data.Common; +using System.Reflection; using FreeSql.Internal.ObjectPool; using ClickHouse.Client.ADO; +using FreeSql.Provider.ClickHouse.Attributes; namespace FreeSql.ClickHouse { @@ -95,10 +97,11 @@ namespace FreeSql.ClickHouse { var arrayDbType = $"Array({value.dbtype})"; var defaultArray = new ArrayList(0); - return new DbInfoResult(Convert.ToInt32(DbType.Object), arrayDbType, arrayDbType, false,defaultArray); + return new DbInfoResult(Convert.ToInt32(DbType.Object), arrayDbType, arrayDbType, false, + defaultArray); } - } + return null; } @@ -132,7 +135,7 @@ namespace FreeSql.ClickHouse if (interfaces.Any(t => t.Name == "IEnumerable")) flag = true; - if (type.Name == "Array") + if (type.Name == "Array") { flag = true; resultType = typeof(string); @@ -173,7 +176,8 @@ namespace FreeSql.ClickHouse if (tb == null) throw new Exception(CoreStrings.S_Type_IsNot_Migrable(obj.tableSchema.Type.FullName)); if (tb.Columns.Any() == false) - throw new Exception(CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.tableSchema.Type.FullName)); + throw new Exception( + CoreStrings.S_Type_IsNot_Migrable_0Attributes(obj.tableSchema.Type.FullName)); var tbname = _commonUtils.SplitTableName(tb.DbName); if (tbname?.Length == 1) tbname = new[] { database, tbname[0] }; @@ -258,7 +262,8 @@ namespace FreeSql.ClickHouse if (tb.Primarys.Any()) { - var primaryKeys = string.Join(",", tb.Primarys.Select(p => _commonUtils.QuoteSqlName(p.Attribute.Name))); + var primaryKeys = string.Join(",", + tb.Primarys.Select(p => _commonUtils.QuoteSqlName(p.Attribute.Name))); sb.Append(" \r\n PRIMARY KEY "); sb.Append($"( {primaryKeys} ) "); } @@ -268,14 +273,32 @@ namespace FreeSql.ClickHouse if (tb.Primarys.Any()) { - var primaryKeys = string.Join(",", tb.Primarys.Select(p => _commonUtils.QuoteSqlName(p.Attribute.Name))); + var primaryKeys = string.Join(",", + tb.Primarys.Select(p => _commonUtils.QuoteSqlName(p.Attribute.Name))); sb.Append(" \r\nORDER BY "); sb.Append($"( {primaryKeys} ) "); } + //查找属性是否标记了分区特性 + var partitionColumnInfos = tb.Properties.Where( + c => c.Value.GetCustomAttribute() != null).ToList(); + + if (partitionColumnInfos != null && partitionColumnInfos.Any()) + { + var partitionProperty = partitionColumnInfos.First(); + + var partitionColumnInfo = tb.Columns.FirstOrDefault(pair => + pair.Value.CsName == partitionProperty.Value.Name); + var partitionName = _commonUtils.QuoteSqlName(partitionColumnInfo.Value.Attribute.Name); + var partitionAttribute = partitionProperty.Value + .GetCustomAttribute(); + sb.Append($" \r\nPARTITION BY {string.Format(partitionAttribute.Format, partitionName)}"); + } + + //if (string.IsNullOrEmpty(tb.Comment) == false) // sb.Append(" Comment=").Append(_commonUtils.FormatSql("{0}", tb.Comment)); - sb.Append(" SETTINGS index_granularity = 8192;\r\n"); + sb.Append(" \r\nSETTINGS index_granularity = 8192;\r\n"); continue; } @@ -477,7 +500,8 @@ where a.database in ({0}) and a.table in ({1})", tboldname ?? tbname); if (tb.Primarys.Any()) { - var primaryKeys = string.Join(",", tb.Primarys.Select(p => _commonUtils.QuoteSqlName(p.Attribute.Name))); + var primaryKeys = string.Join(",", + tb.Primarys.Select(p => _commonUtils.QuoteSqlName(p.Attribute.Name))); sb.Append(" \r\nORDER BY ( "); sb.Append(primaryKeys); sb.Append(" )");