- 增加 UseMappingPriority 指定映射优先级;#387 #69 #99

This commit is contained in:
2881099 2022-06-01 09:38:59 +08:00
parent 184d11d692
commit 7290109734
4 changed files with 399 additions and 227 deletions

View File

@ -1413,6 +1413,24 @@
<param name="convertType"></param> <param name="convertType"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.FreeSqlBuilder.UseMappingPriority(FreeSql.Internal.MappingPriorityType,FreeSql.Internal.MappingPriorityType,FreeSql.Internal.MappingPriorityType)">
<summary>
指定映射优先级<para></para>
例如表名:实体类名 &lt; Aop &lt; FluentApi &lt; Attribute &lt; AsTable<para></para>
事件 Aop -------> fsql.Aop.ConfigEntity/fsql.Aop.ConfigEntityProperty<para></para>
方法 FluentApi -> fsql.CodeFirst.ConfigEntity/fsql.CodeFirst.Entity<para></para>
特性 Attribute -> [Table(Name = xxx, ...)]<para></para>
-----------------------------------------------------------------------------<para></para>
默认规则关于映射优先级Attribute 可以更直观排查问题,即使任何地方使用 FluentApi/Aop 设置 TableName 都不生效。<para></para>
调整规则UseMappingPriority(Attribute, FluentApi, Aop) <para></para>
实体类名 &lt; Attribute &lt; FluentApi &lt; Aop &lt; AsTable
</summary>
<param name="mappingType1"></param>
<param name="mappingType2"></param>
<param name="mappingType3"></param>
<returns></returns>
<exception cref="T:System.ArgumentException"></exception>
</member>
<member name="M:FreeSql.FreeSqlBuilder.UseExitAutoDisposePool(System.Boolean)"> <member name="M:FreeSql.FreeSqlBuilder.UseExitAutoDisposePool(System.Boolean)">
<summary> <summary>
监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池<para></para> 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池<para></para>
@ -4037,6 +4055,112 @@
更新的实体 更新的实体
</summary> </summary>
</member> </member>
<member name="T:FreeSql.Internal.MappingPriorityType">
<summary>
映射优先级,默认: Attribute > FluentApi > Aop
</summary>
</member>
<member name="F:FreeSql.Internal.MappingPriorityType.Attribute">
<summary>
实体特性<para></para>
[Table(Name = "tabname")]<para></para>
[Column(Name = "table_id")]
</summary>
</member>
<member name="F:FreeSql.Internal.MappingPriorityType.FluentApi">
<summary>
流式接口<para></para>
fsql.CodeFirst.ConfigEntity(a => a.Name("tabname"))<para></para>
fsql.CodeFirst.ConfigEntity(a => a.Property(b => b.Id).Name("table_id"))
</summary>
</member>
<member name="F:FreeSql.Internal.MappingPriorityType.Aop">
<summary>
AOP 特性 https://github.com/dotnetcore/FreeSql/wiki/AOP<para></para>
fsql.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = "public.tabname";<para></para>
fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = "table_id";<para></para>
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.None">
<summary>
不进行任何处理
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.PascalCaseToUnderscore">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串
<para></para>
BigApple -> Big_Apple
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.PascalCaseToUnderscoreWithUpper">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
<para></para>
BigApple -> BIG_APPLE
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.PascalCaseToUnderscoreWithLower">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
<para></para>
BigApple -> big_apple
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.ToUpper">
<summary>
将字符串转换为大写
<para></para>
BigApple -> BIGAPPLE
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.ToLower">
<summary>
将字符串转换为小写
<para></para>
BigApple -> bigapple
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.None">
<summary>
不进行任何处理
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscore">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串
<para></para>
BigApple -> Big_Apple
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscoreWithUpper">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
<para></para>
BigApple -> BIG_APPLE
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscoreWithLower">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
<para></para>
BigApple -> big_apple
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.Upper">
<summary>
将字符串转换为大写
<para></para>
BigApple -> BIGAPPLE
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.Lower">
<summary>
将字符串转换为小写
<para></para>
BigApple -> bigapple
</summary>
</member>
<member name="M:FreeSql.Internal.GlobalFilter.Apply``1(System.String,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})"> <member name="M:FreeSql.Internal.GlobalFilter.Apply``1(System.String,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}})">
<summary> <summary>
创建一个过滤器<para></para> 创建一个过滤器<para></para>
@ -4336,6 +4460,7 @@
将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用
</summary> </summary>
<param name="exception"></param> <param name="exception"></param>
<param name="lastGetTime"></param>
<returns>由【可用】变成【不可用】时返回true否则返回false</returns> <returns>由【可用】变成【不可用】时返回true否则返回false</returns>
</member> </member>
<member name="P:FreeSql.Internal.ObjectPool.IObjectPool`1.Statistics"> <member name="P:FreeSql.Internal.ObjectPool.IObjectPool`1.Statistics">
@ -4545,86 +4670,6 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="F:FreeSql.Internal.StringConvertType.None">
<summary>
不进行任何处理
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscore">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串
<para></para>
BigApple -> Big_Apple
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscoreWithUpper">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
<para></para>
BigApple -> BIG_APPLE
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.PascalCaseToUnderscoreWithLower">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
<para></para>
BigApple -> big_apple
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.Upper">
<summary>
将字符串转换为大写
<para></para>
BigApple -> BIGAPPLE
</summary>
</member>
<member name="F:FreeSql.Internal.StringConvertType.Lower">
<summary>
将字符串转换为小写
<para></para>
BigApple -> bigapple
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.None">
<summary>
不进行任何处理
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.PascalCaseToUnderscore">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串
<para></para>
BigApple -> Big_Apple
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.PascalCaseToUnderscoreWithUpper">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
<para></para>
BigApple -> BIG_APPLE
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.PascalCaseToUnderscoreWithLower">
<summary>
将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
<para></para>
BigApple -> big_apple
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.ToUpper">
<summary>
将字符串转换为大写
<para></para>
BigApple -> BIGAPPLE
</summary>
</member>
<member name="F:FreeSql.Internal.NameConvertType.ToLower">
<summary>
将字符串转换为小写
<para></para>
BigApple -> bigapple
</summary>
</member>
<member name="T:FreeSql.CoreStrings"> <member name="T:FreeSql.CoreStrings">
<summary> <summary>
<para> <para>

View File

@ -6,6 +6,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using FreeSql.DataAnnotations; using FreeSql.DataAnnotations;
using FreeSql.Internal; using FreeSql.Internal;
using FreeSql.Internal.CommonProvider;
namespace FreeSql namespace FreeSql
{ {
@ -24,6 +25,7 @@ namespace FreeSql
bool _isGenerateCommandParameterWithLambda = false; bool _isGenerateCommandParameterWithLambda = false;
bool _isLazyLoading = false; bool _isLazyLoading = false;
bool _isExitAutoDisposePool = true; bool _isExitAutoDisposePool = true;
MappingPriorityType[] _mappingPriorityTypes;
StringConvertType _entityPropertyConvertType = StringConvertType.None; StringConvertType _entityPropertyConvertType = StringConvertType.None;
NameConvertType _nameConvertType = NameConvertType.None; NameConvertType _nameConvertType = NameConvertType.None;
Action<DbCommand> _aopCommandExecuting = null; Action<DbCommand> _aopCommandExecuting = null;
@ -160,6 +162,29 @@ namespace FreeSql
return this; return this;
} }
/// <summary>
/// 指定映射优先级<para></para>
/// 例如表名:实体类名 &lt; Aop &lt; FluentApi &lt; Attribute &lt; AsTable<para></para>
/// 事件 Aop -------> fsql.Aop.ConfigEntity/fsql.Aop.ConfigEntityProperty<para></para>
/// 方法 FluentApi -> fsql.CodeFirst.ConfigEntity/fsql.CodeFirst.Entity<para></para>
/// 特性 Attribute -> [Table(Name = xxx, ...)]<para></para>
/// -----------------------------------------------------------------------------<para></para>
/// 默认规则关于映射优先级Attribute 可以更直观排查问题,即使任何地方使用 FluentApi/Aop 设置 TableName 都不生效。<para></para>
/// 调整规则UseMappingPriority(Attribute, FluentApi, Aop) <para></para>
/// 实体类名 &lt; Attribute &lt; FluentApi &lt; Aop &lt; AsTable
/// </summary>
/// <param name="mappingType1"></param>
/// <param name="mappingType2"></param>
/// <param name="mappingType3"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public FreeSqlBuilder UseMappingPriority(MappingPriorityType mappingType1, MappingPriorityType mappingType2, MappingPriorityType mappingType3)
{
if (mappingType1 == mappingType2 || mappingType1 == mappingType3 || mappingType2 == mappingType3) throw new ArgumentException($"{nameof(mappingType1)}、{nameof(mappingType2)}、{nameof(mappingType3)} 不可以相等");
_mappingPriorityTypes = new[] { mappingType1, mappingType2, mappingType3 };
return this;
}
/// <summary> /// <summary>
/// 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池<para></para> /// 监听 AppDomain.CurrentDomain.ProcessExit/Console.CancelKeyPress 事件自动释放连接池<para></para>
/// 默认值: true /// 默认值: true
@ -298,6 +323,9 @@ namespace FreeSql
ret.CodeFirst.IsGenerateCommandParameterWithLambda = _isGenerateCommandParameterWithLambda; ret.CodeFirst.IsGenerateCommandParameterWithLambda = _isGenerateCommandParameterWithLambda;
ret.CodeFirst.IsLazyLoading = _isLazyLoading; ret.CodeFirst.IsLazyLoading = _isLazyLoading;
if (_mappingPriorityTypes != null)
(ret.Select<object>() as Select0Provider)._commonUtils._mappingPriorityTypes = _mappingPriorityTypes;
if (_aopCommandExecuting != null) if (_aopCommandExecuting != null)
ret.Aop.CommandBefore += new EventHandler<Aop.CommandBeforeEventArgs>((s, e) => _aopCommandExecuting?.Invoke(e.Command)); ret.Aop.CommandBefore += new EventHandler<Aop.CommandBeforeEventArgs>((s, e) => _aopCommandExecuting?.Invoke(e.Command));
if (_aopCommandExecuted != null) if (_aopCommandExecuted != null)

View File

@ -111,33 +111,49 @@ namespace FreeSql.Internal
{ {
return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null; return dicConfigEntity.TryGetValue(type, out var trytb) ? trytb : null;
} }
public MappingPriorityType[] _mappingPriorityTypes = new[] { MappingPriorityType.Aop, MappingPriorityType.FluentApi, MappingPriorityType.Attribute };
public TableAttribute GetEntityTableAttribute(Type type) public TableAttribute GetEntityTableAttribute(Type type)
{ {
TableAttribute attr = null; var attr = new TableAttribute();
if (_orm.Aop.ConfigEntityHandler != null) foreach (var mp in _mappingPriorityTypes)
{ {
var aope = new Aop.ConfigEntityEventArgs(type); switch (mp)
_orm.Aop.ConfigEntityHandler(_orm, aope); {
attr = aope.ModifyResult; case MappingPriorityType.Aop:
} if (_orm.Aop.ConfigEntityHandler != null)
if (attr == null) attr = new TableAttribute(); {
if (dicConfigEntity.TryGetValue(type, out var trytb)) var aope = new Aop.ConfigEntityEventArgs(type);
{ _orm.Aop.ConfigEntityHandler(_orm, aope);
if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name; var tryattr = aope.ModifyResult;
if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName; if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name;
if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
if (!string.IsNullOrEmpty(trytb.AsTable)) attr.AsTable = trytb.AsTable; if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure;
if (!string.IsNullOrEmpty(tryattr.AsTable)) attr.AsTable = tryattr.AsTable;
} }
var attrs = type.GetCustomAttributes(typeof(TableAttribute), false); break;
foreach (var tryattrobj in attrs) case MappingPriorityType.FluentApi:
{ if (dicConfigEntity.TryGetValue(type, out var trytb))
var tryattr = tryattrobj as TableAttribute; {
if (tryattr == null) continue; if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name;
if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName;
if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure;
if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure; if (!string.IsNullOrEmpty(trytb.AsTable)) attr.AsTable = trytb.AsTable;
if (!string.IsNullOrEmpty(tryattr.AsTable)) attr.AsTable = tryattr.AsTable; }
break;
case MappingPriorityType.Attribute:
var attrs = type.GetCustomAttributes(typeof(TableAttribute), false);
foreach (var tryattrobj in attrs)
{
var tryattr = tryattrobj as TableAttribute;
if (tryattr == null) continue;
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;
}
break;
}
} }
if (!string.IsNullOrEmpty(attr.Name)) return attr; if (!string.IsNullOrEmpty(attr.Name)) return attr;
if (!string.IsNullOrEmpty(attr.OldName)) return attr; if (!string.IsNullOrEmpty(attr.OldName)) return attr;
@ -147,60 +163,90 @@ namespace FreeSql.Internal
} }
public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto)
{ {
ColumnAttribute attr = null; var attr = new ColumnAttribute();
if (_orm.Aop.ConfigEntityPropertyHandler != null) foreach (var mp in _mappingPriorityTypes)
{ {
var aope = new Aop.ConfigEntityPropertyEventArgs(type, proto); switch (mp)
_orm.Aop.ConfigEntityPropertyHandler(_orm, aope); {
attr = aope.ModifyResult; case MappingPriorityType.Aop:
} if (_orm.Aop.ConfigEntityPropertyHandler != null)
if (attr == null) attr = new ColumnAttribute(); {
if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol)) var aope = new Aop.ConfigEntityPropertyEventArgs(type, proto);
{ _orm.Aop.ConfigEntityPropertyHandler(_orm, aope);
if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name; var tryattr = aope.ModifyResult;
if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName; if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name;
if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType; if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary; if (!string.IsNullOrEmpty(tryattr.DbType)) attr.DbType = tryattr.DbType;
if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity; if (tryattr._IsPrimary != null) attr._IsPrimary = tryattr.IsPrimary;
if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable; if (tryattr._IsIdentity != null) attr._IsIdentity = tryattr.IsIdentity;
if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore; if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable;
if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion; if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore;
if (trycol.MapType != null) attr.MapType = trycol.MapType; if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion;
if (trycol._Position != null) attr._Position = trycol.Position; if (tryattr.MapType != null) attr.MapType = tryattr.MapType;
if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert; if (tryattr._Position != null) attr._Position = tryattr.Position;
if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate; if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert;
if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime; if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate;
if (trycol._StringLength != null) attr.StringLength = trycol.StringLength; if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime;
if (!string.IsNullOrEmpty(trycol.InsertValueSql)) attr.InsertValueSql = trycol.InsertValueSql; if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength;
if (trycol._Precision != null) attr.Precision = trycol.Precision; if (!string.IsNullOrEmpty(tryattr.InsertValueSql)) attr.InsertValueSql = tryattr.InsertValueSql;
if (trycol._Scale != null) attr.Scale = trycol.Scale; if (tryattr._Precision != null) attr.Precision = tryattr.Precision;
if (!string.IsNullOrEmpty(trycol.RewriteSql)) attr.RewriteSql = trycol.RewriteSql; if (tryattr._Scale != null) attr.Scale = tryattr.Scale;
if (!string.IsNullOrEmpty(trycol.RereadSql)) attr.RereadSql = trycol.RereadSql; if (!string.IsNullOrEmpty(tryattr.RewriteSql)) attr.RewriteSql = tryattr.RewriteSql;
} if (!string.IsNullOrEmpty(tryattr.RereadSql)) attr.RereadSql = tryattr.RereadSql;
var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false); }
foreach (var tryattrobj in attrs) break;
{ case MappingPriorityType.FluentApi:
var tryattr = tryattrobj as ColumnAttribute; if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol))
if (tryattr == null) continue; {
if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name; if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name;
if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName; if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName;
if (!string.IsNullOrEmpty(tryattr.DbType)) attr.DbType = tryattr.DbType; if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType;
if (tryattr._IsPrimary != null) attr._IsPrimary = tryattr.IsPrimary; if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary;
if (tryattr._IsIdentity != null) attr._IsIdentity = tryattr.IsIdentity; if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity;
if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable; if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable;
if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore; if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore;
if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion; if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion;
if (tryattr.MapType != null) attr.MapType = tryattr.MapType; if (trycol.MapType != null) attr.MapType = trycol.MapType;
if (tryattr._Position != null) attr._Position = tryattr.Position; if (trycol._Position != null) attr._Position = trycol.Position;
if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert; if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert;
if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate; if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate;
if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime; if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime;
if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength; if (trycol._StringLength != null) attr.StringLength = trycol.StringLength;
if (!string.IsNullOrEmpty(tryattr.InsertValueSql)) attr.InsertValueSql = tryattr.InsertValueSql; if (!string.IsNullOrEmpty(trycol.InsertValueSql)) attr.InsertValueSql = trycol.InsertValueSql;
if (tryattr._Precision != null) attr.Precision = tryattr.Precision; if (trycol._Precision != null) attr.Precision = trycol.Precision;
if (tryattr._Scale != null) attr.Scale = tryattr.Scale; if (trycol._Scale != null) attr.Scale = trycol.Scale;
if (!string.IsNullOrEmpty(tryattr.RewriteSql)) attr.RewriteSql = tryattr.RewriteSql; if (!string.IsNullOrEmpty(trycol.RewriteSql)) attr.RewriteSql = trycol.RewriteSql;
if (!string.IsNullOrEmpty(tryattr.RereadSql)) attr.RereadSql = tryattr.RereadSql; if (!string.IsNullOrEmpty(trycol.RereadSql)) attr.RereadSql = trycol.RereadSql;
}
break;
case MappingPriorityType.Attribute:
var attrs = proto.GetCustomAttributes(typeof(ColumnAttribute), false);
foreach (var tryattrobj in attrs)
{
var tryattr = tryattrobj as ColumnAttribute;
if (tryattr == null) continue;
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;
if (tryattr._IsIdentity != null) attr._IsIdentity = tryattr.IsIdentity;
if (tryattr._IsNullable != null) attr._IsNullable = tryattr.IsNullable;
if (tryattr._IsIgnore != null) attr._IsIgnore = tryattr.IsIgnore;
if (tryattr._IsVersion != null) attr._IsVersion = tryattr.IsVersion;
if (tryattr.MapType != null) attr.MapType = tryattr.MapType;
if (tryattr._Position != null) attr._Position = tryattr.Position;
if (tryattr._CanInsert != null) attr._CanInsert = tryattr.CanInsert;
if (tryattr._CanUpdate != null) attr._CanUpdate = tryattr.CanUpdate;
if (tryattr.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = tryattr.ServerTime;
if (tryattr._StringLength != null) attr.StringLength = tryattr.StringLength;
if (!string.IsNullOrEmpty(tryattr.InsertValueSql)) attr.InsertValueSql = tryattr.InsertValueSql;
if (tryattr._Precision != null) attr.Precision = tryattr.Precision;
if (tryattr._Scale != null) attr.Scale = tryattr.Scale;
if (!string.IsNullOrEmpty(tryattr.RewriteSql)) attr.RewriteSql = tryattr.RewriteSql;
if (!string.IsNullOrEmpty(tryattr.RereadSql)) attr.RereadSql = tryattr.RereadSql;
}
break;
}
} }
ColumnAttribute ret = null; ColumnAttribute ret = null;
if (!string.IsNullOrEmpty(attr.Name)) ret = attr; if (!string.IsNullOrEmpty(attr.Name)) ret = attr;
@ -228,18 +274,31 @@ namespace FreeSql.Internal
public NavigateAttribute GetEntityNavigateAttribute(Type type, PropertyInfo proto) public NavigateAttribute GetEntityNavigateAttribute(Type type, PropertyInfo proto)
{ {
var attr = new NavigateAttribute(); var attr = new NavigateAttribute();
if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._navigates.TryGetValue(proto.Name, out var trynav)) foreach (var mp in _mappingPriorityTypes)
{ {
if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind; switch (mp)
if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany; {
} case MappingPriorityType.Aop:
var attrs = proto.GetCustomAttributes(typeof(NavigateAttribute), false);
foreach (var tryattrobj in attrs) break;
{ case MappingPriorityType.FluentApi:
trynav = tryattrobj as NavigateAttribute; if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._navigates.TryGetValue(proto.Name, out var trynav))
if (trynav == null) continue; {
if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind; if (!string.IsNullOrEmpty(trynav.Bind)) attr.Bind = trynav.Bind;
if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany; if (trynav.ManyToMany != null) attr.ManyToMany = trynav.ManyToMany;
}
break;
case MappingPriorityType.Attribute:
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;
}
break;
}
} }
NavigateAttribute ret = null; NavigateAttribute ret = null;
if (!string.IsNullOrEmpty(attr.Bind)) ret = attr; if (!string.IsNullOrEmpty(attr.Bind)) ret = attr;
@ -249,35 +308,47 @@ namespace FreeSql.Internal
public IndexAttribute[] GetEntityIndexAttribute(Type type) public IndexAttribute[] GetEntityIndexAttribute(Type type)
{ {
var ret = new Dictionary<string, IndexAttribute>(); var ret = new Dictionary<string, IndexAttribute>();
if (_orm.Aop.ConfigEntityHandler != null) foreach (var mp in _mappingPriorityTypes)
{ {
var aope = new Aop.ConfigEntityEventArgs(type); switch (mp)
_orm.Aop.ConfigEntityHandler(_orm, aope);
foreach (var idxattr in aope.ModifyIndexResult)
if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields))
{
if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name);
ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique });
}
}
if (dicConfigEntity.TryGetValue(type, out var trytb))
{
foreach (var idxattr in trytb._indexs.Values)
if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields))
{
if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name);
ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique });
}
}
var attrs = type.GetCustomAttributes(typeof(IndexAttribute), true);
foreach (var tryattrobj in attrs)
{
var idxattr = tryattrobj as IndexAttribute;
if (idxattr == null) continue;
if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields))
{ {
if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name); case MappingPriorityType.Aop:
ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique }); if (_orm.Aop.ConfigEntityHandler != null)
{
var aope = new Aop.ConfigEntityEventArgs(type);
_orm.Aop.ConfigEntityHandler(_orm, aope);
foreach (var idxattr in aope.ModifyIndexResult)
if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields))
{
if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name);
ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique });
}
}
break;
case MappingPriorityType.FluentApi:
if (dicConfigEntity.TryGetValue(type, out var trytb))
{
foreach (var idxattr in trytb._indexs.Values)
if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields))
{
if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name);
ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique });
}
}
break;
case MappingPriorityType.Attribute:
var attrs = type.GetCustomAttributes(typeof(IndexAttribute), true);
foreach (var tryattrobj in attrs)
{
var idxattr = tryattrobj as IndexAttribute;
if (idxattr == null) continue;
if (!string.IsNullOrEmpty(idxattr.Name) && !string.IsNullOrEmpty(idxattr.Fields))
{
if (ret.ContainsKey(idxattr.Name)) ret.Remove(idxattr.Name);
ret.Add(idxattr.Name, new IndexAttribute(idxattr.Name, idxattr.Fields) { _IsUnique = idxattr._IsUnique });
}
}
break;
} }
} }
return ret.Values.ToArray(); return ret.Values.ToArray();

View File

@ -2,47 +2,31 @@
namespace FreeSql.Internal namespace FreeSql.Internal
{ {
public enum StringConvertType /// <summary>
/// 映射优先级,默认: Attribute > FluentApi > Aop
/// </summary>
public enum MappingPriorityType
{ {
/// <summary> /// <summary>
/// 不进行任何处理 /// 实体特性<para></para>
/// [Table(Name = "tabname")]<para></para>
/// [Column(Name = "table_id")]
/// </summary> /// </summary>
None = 0, Attribute = 0,
/// <summary> /// <summary>
/// 将帕斯卡命名字符串转换为下划线分隔字符串 /// 流式接口<para></para>
/// <para></para> /// fsql.CodeFirst.ConfigEntity(a => a.Name("tabname"))<para></para>
/// BigApple -> Big_Apple /// fsql.CodeFirst.ConfigEntity(a => a.Property(b => b.Id).Name("table_id"))
/// </summary> /// </summary>
PascalCaseToUnderscore, FluentApi,
/// <summary> /// <summary>
/// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写 /// AOP 特性 https://github.com/dotnetcore/FreeSql/wiki/AOP<para></para>
/// <para></para> /// fsql.Aop.ConfigEntity += (_, e) => e.ModifyResult.Name = "public.tabname";<para></para>
/// BigApple -> BIG_APPLE /// fsql.Aop.ConfigEntityProperty += (_, e) => e.ModifyResult.Name = "table_id";<para></para>
/// </summary> /// </summary>
PascalCaseToUnderscoreWithUpper, Aop
/// <summary>
/// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
/// <para></para>
/// BigApple -> big_apple
/// </summary>
PascalCaseToUnderscoreWithLower,
/// <summary>
/// 将字符串转换为大写
/// <para></para>
/// BigApple -> BIGAPPLE
/// </summary>
Upper,
/// <summary>
/// 将字符串转换为小写
/// <para></para>
/// BigApple -> bigapple
/// </summary>
Lower
} }
public enum NameConvertType public enum NameConvertType
@ -94,4 +78,48 @@ namespace FreeSql.Internal
/// </summary> /// </summary>
ToLower ToLower
} }
public enum StringConvertType
{
/// <summary>
/// 不进行任何处理
/// </summary>
None = 0,
/// <summary>
/// 将帕斯卡命名字符串转换为下划线分隔字符串
/// <para></para>
/// BigApple -> Big_Apple
/// </summary>
PascalCaseToUnderscore,
/// <summary>
/// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全大写
/// <para></para>
/// BigApple -> BIG_APPLE
/// </summary>
PascalCaseToUnderscoreWithUpper,
/// <summary>
/// 将帕斯卡命名字符串转换为下划线分隔字符串,且转换为全小写
/// <para></para>
/// BigApple -> big_apple
/// </summary>
PascalCaseToUnderscoreWithLower,
/// <summary>
/// 将字符串转换为大写
/// <para></para>
/// BigApple -> BIGAPPLE
/// </summary>
Upper,
/// <summary>
/// 将字符串转换为小写
/// <para></para>
/// BigApple -> bigapple
/// </summary>
Lower
}
} }