From c747d39db82401c64a21786586aad46e3ea08ce4 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Thu, 26 Sep 2019 11:51:50 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20NavigateAttribute=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E5=AF=B9=E5=BA=94=E7=9A=84=20Fluent=20?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9B#96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/DataAnnotations/TableAttribute.cs | 1 + FreeSql/DataAnnotations/TableFluent.cs | 17 +++++++++++++++++ FreeSql/FreeSql.xml | 10 ++++++++++ FreeSql/Internal/CommonUtils.cs | 21 +++++++++++++++++++++ FreeSql/Internal/UtilsExpressionTree.cs | 4 ++-- 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/FreeSql/DataAnnotations/TableAttribute.cs b/FreeSql/DataAnnotations/TableAttribute.cs index b70858b4..ef5a4dda 100644 --- a/FreeSql/DataAnnotations/TableAttribute.cs +++ b/FreeSql/DataAnnotations/TableAttribute.cs @@ -26,5 +26,6 @@ namespace FreeSql.DataAnnotations public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; } internal ConcurrentDictionary _columns { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); + internal ConcurrentDictionary _navigates { get; } = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); } } diff --git a/FreeSql/DataAnnotations/TableFluent.cs b/FreeSql/DataAnnotations/TableFluent.cs index 0e6d1155..9027d529 100644 --- a/FreeSql/DataAnnotations/TableFluent.cs +++ b/FreeSql/DataAnnotations/TableFluent.cs @@ -111,5 +111,22 @@ namespace FreeSql.DataAnnotations var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); return new ColumnFluent(col); } + + /// + /// 导航关系Fluent,与 NavigateAttribute 对应 + /// + /// + /// + /// + /// 多对多关系的中间实体类型 + /// + public TableFluent Navigate(Expression> proto, string bind, Type manyToMany = null) + { + var member = (proto.Body as MemberExpression)?.Member; + if (member == null) throw new FormatException($"错误的表达式格式 {proto}"); + var nav = new NavigateAttribute { Bind = bind, ManyToMany = manyToMany }; + _table._navigates.AddOrUpdate(member.Name, nav, (name, old) => nav); + return this; + } } } diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 6ba2f4df..1bab4823 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -215,6 +215,16 @@ 禁用 CodeFirst 同步结构迁移 + + + 导航关系Fluent,与 NavigateAttribute 对应 + + + + + 多对多关系的中间实体类型 + + 所属表 diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index a1bce7e8..6f065895 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -164,6 +164,27 @@ namespace FreeSql.Internal if (ret != null && ret.MapType == null) ret.MapType = proto.PropertyType; return ret; } + public NavigateAttribute GetEntityNavigateAttribute(Type type, PropertyInfo proto) + { + var attr = new NavigateAttribute(); + if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._navigates.TryGetValue(proto.Name, out var trynav)) + { + if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind; + if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany; + } + var attrs = proto.GetCustomAttributes(typeof(NavigateAttribute), false); + foreach (var tryattrobj in attrs) + { + trynav = tryattrobj as NavigateAttribute; + if (trynav == null) continue; + if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind; + if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany; + } + NavigateAttribute ret = null; + if (!string.IsNullOrEmpty(attr.Bind)) ret = attr; + if (attr.ManyToMany != null) ret = attr; + return ret; + } public string WhereObject(TableInfo table, string aliasAndDot, object dywhere) { diff --git a/FreeSql/Internal/UtilsExpressionTree.cs b/FreeSql/Internal/UtilsExpressionTree.cs index 6c997710..09a3fac4 100644 --- a/FreeSql/Internal/UtilsExpressionTree.cs +++ b/FreeSql/Internal/UtilsExpressionTree.cs @@ -311,7 +311,7 @@ namespace FreeSql.Internal $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name.Remove(pnv.PropertyType.Name.IndexOf('`'))}<{string.Join(", ", pnv.PropertyType.GenericTypeArguments.Select(a => a.IsNested ? $"{a.DeclaringType.Namespace?.NotNullAndConcat(".")}{a.DeclaringType.Name}.{a.Name}" : $"{a.Namespace?.NotNullAndConcat(".")}{a.Name}"))}>" : (pnv.PropertyType.IsNested ? $"{pnv.PropertyType.DeclaringType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.DeclaringType.Name}.{pnv.PropertyType.Name}" : $"{pnv.PropertyType.Namespace?.NotNullAndConcat(".")}{pnv.PropertyType.Name}"); - var pnvAttr = pnv.GetCustomAttribute(); + var pnvAttr = common.GetEntityNavigateAttribute(trytb.Type, pnv); var pnvBind = pnvAttr?.Bind?.Split(',').Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToArray(); var nvref = new TableRef(); nvref.Property = pnv; @@ -351,7 +351,7 @@ namespace FreeSql.Internal { isManyToMany = propElementType != trytb.Type && tbref.Properties.Where(z => (z.Value.PropertyType.GenericTypeArguments.FirstOrDefault() == trytb.Type || z.Value.PropertyType.GetElementType() == trytb.Type) && - z.Value.GetCustomAttribute()?.ManyToMany == pnvAttr.ManyToMany && + common.GetEntityNavigateAttribute(tbref.Type, z.Value)?.ManyToMany == pnvAttr.ManyToMany && typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any(); if (isManyToMany == false)