From 9e173aed5f3af56f129a5471c6a1f56a04a027e9 Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Thu, 11 Jul 2024 19:00:24 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20Aop=20=E5=8A=A8?= =?UTF-8?q?=E6=80=81=20TableName=20=E8=AE=BE=E7=BD=AE=EF=BC=9B#364=20#1835?= =?UTF-8?q?=20#1729=20#1542=20#1248=20#1247=20#407=20#387?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/base_entity/Program.cs | 31 ++++++++++++++-- .../DataAnnotations/TableNameTest.cs | 35 +++++++++++++++++++ .../Internal/CommonProvider/DeleteProvider.cs | 9 ++--- .../CommonProvider/InsertOrUpdateProvider.cs | 13 ++++--- .../Internal/CommonProvider/InsertProvider.cs | 6 ++-- .../SelectProvider/Select0Provider.cs | 2 +- .../Internal/CommonProvider/UpdateProvider.cs | 11 +++--- FreeSql/Internal/CommonUtils.cs | 33 +++++++++++++++-- 8 files changed, 117 insertions(+), 23 deletions(-) create mode 100644 FreeSql.Tests/FreeSql.Tests/DataAnnotations/TableNameTest.cs diff --git a/Examples/base_entity/Program.cs b/Examples/base_entity/Program.cs index 37d9bc3c..bbee45a0 100644 --- a/Examples/base_entity/Program.cs +++ b/Examples/base_entity/Program.cs @@ -565,7 +565,7 @@ namespace base_entity .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) //.UseNameConvert(NameConvertType.ToLower) - //.UseMappingPriority(MappingPriorityType.Attribute, MappingPriorityType.FluentApi, MappingPriorityType.Aop) + .UseMappingPriority(MappingPriorityType.Attribute, MappingPriorityType.FluentApi, MappingPriorityType.Aop) .UseAdoConnectionPool(true) .UseConnectionString(FreeSql.DataType.Sqlite, "data source=123.db") @@ -619,6 +619,18 @@ namespace base_entity BaseEntity.Initialization(fsql, () => _asyncUow.Value); #endregion + fsql.Aop.ConfigEntity += (_, e) => + { + e.ModifyResult.Name = Guid.NewGuid().ToString("n"); + }; + + + + FreeSql.Internal.Utils.TypeHandlers.TryAdd(typeof(DateTimeOffset), new DateTimeOffsetTypeHandler()); + + fsql.Insert(new Account { Name = DateTime.Now.ToString(), Join = DateTimeOffset.Now }).ExecuteAffrows(); + var dtslist01 = fsql.Select().As("aaa").Where(p => p.ID >= 1).AsQueryable().Select(p => new { p.Name, p.ID, p.Join }).ToList(); + fsql.Select().As("aaa").Where(p => p.ID == 1).AsQueryable().Distinct().Select(p => new { p.Name, p.ID, p.Join }).Count(); var sqlc001 = fsql.Select() .GroupBy(a => a.GroupId) @@ -631,7 +643,6 @@ namespace base_entity cou5 = g.Count(g.Value.Sort > 50 || g.Value.Username == "xx"), }); - fsql.Select().As("aaa").Where(p => p.ID == 1).AsQueryable().Distinct().Select(p => new { p.Name, p.ID }).Count(); var sqlt001 = fsql.Select() @@ -3286,8 +3297,22 @@ public partial class ProjectItem [Table(Name = "t_account")] public class Account { - [Column(Name = "FID")] + [Column(Name = "FID", IsIdentity = true)] public int ID { get; set; } [Column(Name = "FName")] public string Name { get; set; } + + [JsonProperty, Column(Name = "join", DbType = "date", MapType = typeof(string))] // 数据库类型也可以是datetime + public DateTimeOffset Join { get; set; } +} +class DateTimeOffsetTypeHandler : TypeHandler +{ + public override object Serialize(DateTimeOffset value) + { + return value.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss"); + } + public override DateTimeOffset Deserialize(object value) + { + return DateTimeOffset.TryParse((string)value, out var dts) ? dts : DateTimeOffset.MinValue; + } } \ No newline at end of file diff --git a/FreeSql.Tests/FreeSql.Tests/DataAnnotations/TableNameTest.cs b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/TableNameTest.cs new file mode 100644 index 00000000..876fa286 --- /dev/null +++ b/FreeSql.Tests/FreeSql.Tests/DataAnnotations/TableNameTest.cs @@ -0,0 +1,35 @@ +using FreeSql.DataAnnotations; +using FreeSql.Internal; +using FreeSql.Internal.Model; +using MySql.Data.MySqlClient; +using System; +using System.Linq; +using Xunit; + +namespace FreeSql.Tests.DataAnnotations +{ + public class TableNameTest + { + IFreeSql fsql => g.sqlite; + + [Fact] + public void ClassTableName() + { + Assert.Equal("", fsql.Select().ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Select().AsTable((t, old) => "tnt01_t").ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Insert().ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Insert().AsTable("tnt01_t").ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Delete().ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Delete().AsTable("tnt01_t").ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Update().SetSource(new tnt01()).ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.Update().SetSource(new tnt01()).AsTable("tnt01_t").ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.InsertOrUpdate().SetSource(new tnt01()).ToSql().Replace("\r\n", "").Trim()); + Assert.Equal("", fsql.InsertOrUpdate().SetSource(new tnt01()).AsTable("tnt01_t").ToSql().Replace("\r\n", "").Trim()); + } + class tnt01 + { + public int id { get; set; } + public string name { get; set; } + } + } +} diff --git a/FreeSql/Internal/CommonProvider/DeleteProvider.cs b/FreeSql/Internal/CommonProvider/DeleteProvider.cs index 1beb2e84..a7e17f3e 100644 --- a/FreeSql/Internal/CommonProvider/DeleteProvider.cs +++ b/FreeSql/Internal/CommonProvider/DeleteProvider.cs @@ -154,10 +154,11 @@ namespace FreeSql.Internal.CommonProvider protected string TableRuleInvoke() { - if (_tableRule == null) return _table.DbName; - var newname = _tableRule(_table.DbName); - if (newname == _table.DbName) return _table.DbName; - if (string.IsNullOrEmpty(newname)) return _table.DbName; + if (_tableRule == null && _table.AsTableImpl == null) return _commonUtils.GetEntityTableAopName(_table, true); + var tbname = _table?.DbName ?? ""; + var newname = _tableRule(tbname); + if (newname == tbname) return tbname; + if (string.IsNullOrEmpty(newname)) return tbname; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); diff --git a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs index fcc6cdfb..c16a798b 100644 --- a/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertOrUpdateProvider.cs @@ -34,6 +34,7 @@ namespace FreeSql.Internal.CommonProvider public DbConnection _connection; public int _commandTimeout = 0; public ColumnInfo IdentityColumn { get; protected set; } + public bool _isAutoSyncStructure; } public abstract partial class InsertOrUpdateProvider : InsertOrUpdateProvider, IInsertOrUpdate where T1 : class @@ -47,10 +48,11 @@ namespace FreeSql.Internal.CommonProvider _commonUtils = commonUtils; _commonExpression = commonExpression; _table = _commonUtils.GetTableByEntity(typeof(T1)); + _isAutoSyncStructure = _orm.CodeFirst.IsAutoSyncStructure; _tempPrimarys = _table?.Primarys ?? new ColumnInfo[0]; if (_table == null && typeof(T1) != typeof(Dictionary)) throw new Exception(CoreStrings.InsertOrUpdate_NotSuport_Generic_UseEntity(typeof(T1))); - if (_orm.CodeFirst.IsAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); + if (_isAutoSyncStructure && typeof(T1) != typeof(object)) _orm.CodeFirst.SyncStructure(); IdentityColumn = _table?.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault(); } @@ -221,8 +223,8 @@ namespace FreeSql.Internal.CommonProvider protected string TableRuleInvoke() { + if (_tableRule == null && _table.AsTableImpl == null) return _commonUtils.GetEntityTableAopName(_table, true); var tbname = _table?.DbName ?? ""; - if (_tableRule == null && _table.AsTableImpl == null) return tbname; string newname = null; if (_table.AsTableImpl != null) { @@ -231,15 +233,15 @@ namespace FreeSql.Internal.CommonProvider else if (_tableRule == null) newname = _table.AsTableImpl.GetTableNameByColumnValue(DateTime.Now); else - newname = _tableRule(_table.DbName); + newname = _tableRule(tbname); } else - newname = _tableRule(_table.DbName); + newname = _tableRule(tbname); if (newname == tbname) return tbname; if (string.IsNullOrEmpty(newname)) return tbname; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); - if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table?.Type, newname); + if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table?.Type, newname); return newname; } public IInsertOrUpdate AsTable(Func tableRule) @@ -258,6 +260,7 @@ namespace FreeSql.Internal.CommonProvider if (entityType == _table.Type) return this; var newtb = _commonUtils.GetTableByEntity(entityType); _table = newtb ?? throw new Exception(CoreStrings.Type_AsType_Parameter_Error("IInsertOrUpdate")); + if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); _tempPrimarys = _table.Primarys; if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(entityType); IdentityColumn = _table.Primarys.Where(a => a.Attribute.IsIdentity).FirstOrDefault(); diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index ebce0379..ab166af6 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -564,8 +564,8 @@ namespace FreeSql.Internal.CommonProvider protected string TableRuleInvoke() { + if (_tableRule == null && _table.AsTableImpl == null) return _commonUtils.GetEntityTableAopName(_table, true); var tbname = _table?.DbName ?? ""; - if (_tableRule == null && _table.AsTableImpl == null) return tbname; string newname = null; if (_table.AsTableImpl != null) { @@ -574,10 +574,10 @@ namespace FreeSql.Internal.CommonProvider else if (_tableRule == null) newname = _table.AsTableImpl.GetTableNameByColumnValue(DateTime.Now); else - newname = _tableRule(_table.DbName); + newname = _tableRule(tbname); } else - newname = _tableRule(_table.DbName); + newname = _tableRule(tbname); if (newname == tbname) return tbname; if (string.IsNullOrEmpty(newname)) return tbname; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); diff --git a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs index f1852104..702891be 100644 --- a/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs +++ b/FreeSql/Internal/CommonProvider/SelectProvider/Select0Provider.cs @@ -877,7 +877,7 @@ namespace FreeSql.Internal.CommonProvider DateTime? DateTimeAsTableImplStart = null, DateTimeAsTableImplEnd = null; string[] LocalGetTableNames(SelectTableInfo tb) { - var trname = trs[0](tb.Table.Type, tb.Table.AsTableImpl != null ? null : tb.Table.DbName); + var trname = trs[0](tb.Table.Type, tb.Table.AsTableImpl != null ? null : _commonUtils.GetEntityTableAopName(tb.Table, false)); if (tb.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trname) == true) { var aret = tb.Table.AsTableImpl.GetTableNamesBySqlWhere(_where.Length == 0 ? null : _where.ToString(), _params, tb, _commonUtils); diff --git a/FreeSql/Internal/CommonProvider/UpdateProvider.cs b/FreeSql/Internal/CommonProvider/UpdateProvider.cs index f3cb4e04..5dd85e25 100644 --- a/FreeSql/Internal/CommonProvider/UpdateProvider.cs +++ b/FreeSql/Internal/CommonProvider/UpdateProvider.cs @@ -897,7 +897,8 @@ namespace FreeSql.Internal.CommonProvider protected string TableRuleInvoke() { - if (_tableRule == null && _table.AsTableImpl == null) return _table.DbName; + if (_tableRule == null && _table.AsTableImpl == null) return _commonUtils.GetEntityTableAopName(_table, true); + var tbname = _table?.DbName ?? ""; string newname = null; if (_table.AsTableImpl != null) { @@ -906,12 +907,12 @@ namespace FreeSql.Internal.CommonProvider else if (_tableRule == null) newname = _table.AsTableImpl.GetTableNameByColumnValue(DateTime.Now); else - newname = _tableRule(_table.DbName); + newname = _tableRule(tbname); } else - newname = _tableRule(_table.DbName); - if (newname == _table.DbName) return _table.DbName; - if (string.IsNullOrEmpty(newname)) return _table.DbName; + newname = _tableRule(tbname); + if (newname == tbname) return tbname; + if (string.IsNullOrEmpty(newname)) return tbname; if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); if (_isAutoSyncStructure) _orm.CodeFirst.SyncStructure(_table.Type, newname); diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index 1ceea938..03ed29d9 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -134,6 +134,35 @@ namespace FreeSql.Internal return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null; } + public string GetEntityTableAopName(TableInfo table, bool flag1) + { + if (table != null && _orm.Aop.ConfigEntityHandler != null && _mappingPriorityTypes.LastOrDefault() == MappingPriorityType.Aop) + { + var newname = table.DbName; + var aope = new Aop.ConfigEntityEventArgs(table.Type) + { + ModifyResult = new TableAttribute + { + Name = table.DbName, + _DisableSyncStructure = table.DisableSyncStructure, + } + }; + _orm.Aop.ConfigEntityHandler(_orm, aope); + var tryattr = aope.ModifyResult; + if (!string.IsNullOrEmpty(tryattr.Name)) newname = tryattr.Name; + + if (newname == table.DbName) return table.DbName; + if (string.IsNullOrEmpty(newname)) return table.DbName; + if (flag1) + { + if (_orm.CodeFirst.IsSyncStructureToLower) newname = newname.ToLower(); + if (_orm.CodeFirst.IsSyncStructureToUpper) newname = newname.ToUpper(); + if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(table.Type, newname); + } + return newname; + } + return table?.DbName; + } public MappingPriorityType[] _mappingPriorityTypes = new[] { MappingPriorityType.Aop, MappingPriorityType.FluentApi, MappingPriorityType.Attribute }; ConcurrentDictionary> dicAopConfigEntityIndex = new ConcurrentDictionary>(); public TableAttribute GetEntityTableAttribute(Type type) @@ -158,7 +187,7 @@ namespace FreeSql.Internal }; _orm.Aop.ConfigEntityHandler(_orm, aope); var tryattr = aope.ModifyResult; - if (!string.IsNullOrEmpty(tryattr.Name) && tryattr.Name != type.Name) attr.Name = tryattr.Name; + if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; if (!string.IsNullOrEmpty(tryattr.AsTable)) attr.AsTable = tryattr.AsTable; @@ -239,7 +268,7 @@ namespace FreeSql.Internal }; _orm.Aop.ConfigEntityPropertyHandler(_orm, aope); var tryattr = aope.ModifyResult; - if (!string.IsNullOrEmpty(tryattr.Name) && tryattr.Name != proto.Name) attr.Name = tryattr.Name; + if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (!string.IsNullOrEmpty(tryattr.DbType)) attr.DbType = tryattr.DbType; if (tryattr._IsPrimary != null) attr._IsPrimary = tryattr.IsPrimary;