- 增加 NavigateAttribute 特性对应的 Fluent 功能;#96

This commit is contained in:
28810 2019-09-26 11:51:50 +08:00
parent 31a42e750e
commit c747d39db8
5 changed files with 51 additions and 2 deletions

View File

@ -26,5 +26,6 @@ namespace FreeSql.DataAnnotations
public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; }
internal ConcurrentDictionary<string, ColumnAttribute> _columns { get; } = new ConcurrentDictionary<string, ColumnAttribute>(StringComparer.CurrentCultureIgnoreCase);
internal ConcurrentDictionary<string, NavigateAttribute> _navigates { get; } = new ConcurrentDictionary<string, NavigateAttribute>(StringComparer.CurrentCultureIgnoreCase);
}
}

View File

@ -111,5 +111,22 @@ namespace FreeSql.DataAnnotations
var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name });
return new ColumnFluent(col);
}
/// <summary>
/// 导航关系Fluent与 NavigateAttribute 对应
/// </summary>
/// <typeparam name="TProto"></typeparam>
/// <param name="proto"></param>
/// <param name="bind"></param>
/// <param name="manyToMany">多对多关系的中间实体类型</param>
/// <returns></returns>
public TableFluent<T> Navigate<TProto>(Expression<Func<T, TProto>> 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;
}
}
}

View File

@ -215,6 +215,16 @@
禁用 CodeFirst 同步结构迁移
</summary>
</member>
<member name="M:FreeSql.DataAnnotations.TableFluent`1.Navigate``1(System.Linq.Expressions.Expression{System.Func{`0,``0}},System.String,System.Type)">
<summary>
导航关系Fluent与 NavigateAttribute 对应
</summary>
<typeparam name="TProto"></typeparam>
<param name="proto"></param>
<param name="bind"></param>
<param name="manyToMany">多对多关系的中间实体类型</param>
<returns></returns>
</member>
<member name="P:FreeSql.DatabaseModel.DbColumnInfo.Table">
<summary>
所属表

View File

@ -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)
{

View File

@ -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<NavigateAttribute>();
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<NavigateAttribute>()?.ManyToMany == pnvAttr.ManyToMany &&
common.GetEntityNavigateAttribute(tbref.Type, z.Value)?.ManyToMany == pnvAttr.ManyToMany &&
typeof(IEnumerable).IsAssignableFrom(z.Value.PropertyType)).Any();
if (isManyToMany == false)