mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 增加 TableAttribute 特性属性 DisableSyncStructure,当实体对应的是视图时,可使用本功能禁用迁移 #61;
- 增加 FreeSqlBuilder UseEntityPropertyNameConvert() 全局转换实体属性名方法 #60;
This commit is contained in:
		@@ -17,6 +17,12 @@ namespace FreeSql.DataAnnotations {
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string SelectFilter { get; set; }
 | 
			
		||||
 | 
			
		||||
		internal bool? _DisableSyncStructure;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// 禁用 CodeFirst 同步结构迁移
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool DisableSyncStructure { get => _DisableSyncStructure ?? false; set => _DisableSyncStructure = value; }
 | 
			
		||||
 | 
			
		||||
		internal ConcurrentDictionary<string, ColumnAttribute> _columns { get; } = new ConcurrentDictionary<string, ColumnAttribute>(StringComparer.CurrentCultureIgnoreCase);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,14 @@ namespace FreeSql.DataAnnotations {
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// 禁用 CodeFirst 同步结构迁移
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public TableFluent DisableSyncStructure(bool value) {
 | 
			
		||||
			_table.DisableSyncStructure = value;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ColumnFluent Property(string proto) {
 | 
			
		||||
			if (_properties.ContainsKey(proto) == false) throw new KeyNotFoundException($"找不到属性名 {proto}");
 | 
			
		||||
			var col = _table._columns.GetOrAdd(proto, name => new ColumnAttribute { Name = proto });
 | 
			
		||||
@@ -74,6 +82,14 @@ namespace FreeSql.DataAnnotations {
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// 禁用 CodeFirst 同步结构迁移
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public TableFluent<T> DisableSyncStructure(bool value) {
 | 
			
		||||
			_table.DisableSyncStructure = value;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ColumnFluent Property<TProto>(Expression<Func<T, TProto>> column) {
 | 
			
		||||
			var proto = (column.Body as MemberExpression)?.Member;
 | 
			
		||||
			if (proto == null) throw new FormatException($"错误的表达式格式 {column}");
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
	<PropertyGroup>
 | 
			
		||||
		<TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
 | 
			
		||||
		<Version>0.6.9</Version>
 | 
			
		||||
		<Version>0.6.10</Version>
 | 
			
		||||
		<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
 | 
			
		||||
		<Authors>YeXiangQin</Authors>
 | 
			
		||||
		<Description>FreeSql is the most convenient ORM in dotnet. It supports Mysql, Postgresql, SqlServer, Oracle and Sqlite.</Description>
 | 
			
		||||
 
 | 
			
		||||
@@ -133,6 +133,11 @@
 | 
			
		||||
            查询过滤SQL,实现类似 a.IsDeleted = 1 功能
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.DataAnnotations.TableAttribute.DisableSyncStructure">
 | 
			
		||||
            <summary>
 | 
			
		||||
            禁用 CodeFirst 同步结构迁移
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.DataAnnotations.TableFluent.Name(System.String)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            数据库表名
 | 
			
		||||
@@ -148,6 +153,11 @@
 | 
			
		||||
            查询过滤SQL,实现类似 a.IsDeleted = 1 功能
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.DataAnnotations.TableFluent.DisableSyncStructure(System.Boolean)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            禁用 CodeFirst 同步结构迁移
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.DataAnnotations.TableFluent`1.Name(System.String)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            数据库表名
 | 
			
		||||
@@ -163,6 +173,11 @@
 | 
			
		||||
            查询过滤SQL,实现类似 a.IsDeleted = 1 功能
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.DataAnnotations.TableFluent`1.DisableSyncStructure(System.Boolean)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            禁用 CodeFirst 同步结构迁移
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.DatabaseModel.DbColumnInfo.Table">
 | 
			
		||||
            <summary>
 | 
			
		||||
            所属表
 | 
			
		||||
@@ -480,6 +495,15 @@
 | 
			
		||||
            <param name="executed">执行后,可监视执行性能</param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.FreeSqlBuilder.UseEntityPropertyNameConvert(FreeSql.Internal.StringConvertType)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            自动转换实体属性名称 Entity Property -> Db Filed
 | 
			
		||||
            <para></para>
 | 
			
		||||
            *不会覆盖 [Column] 特性设置的Name
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="convertType"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IDelete`1.WithTransaction(System.Data.Common.DbTransaction)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            指定事务对象
 | 
			
		||||
@@ -2251,6 +2275,55 @@
 | 
			
		||||
            中间表,多对多
 | 
			
		||||
            </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.StringUtils.PascalCaseToUnderScore(System.String)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            将帕斯卡命名字符串转换为下划线分隔字符串
 | 
			
		||||
            <para></para>
 | 
			
		||||
            BigApple -> Big_Apple
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="str"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSqlGlobalExtensions.Distance(System.Drawing.Point,System.Drawing.Point)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            测量两个经纬度的距离,返回单位:米
 | 
			
		||||
 
 | 
			
		||||
@@ -147,7 +147,7 @@ namespace FreeSql {
 | 
			
		||||
			ret = Activator.CreateInstance(type, new object[] { _masterConnectionString, _slaveConnectionString }) as IFreeSql<TMark>;
 | 
			
		||||
			if (ret != null) {
 | 
			
		||||
				ret.CodeFirst.IsAutoSyncStructure = _isAutoSyncStructure;
 | 
			
		||||
				
 | 
			
		||||
 | 
			
		||||
				ret.CodeFirst.IsSyncStructureToLower = _isSyncStructureToLower;
 | 
			
		||||
				ret.CodeFirst.IsSyncStructureToUpper = _isSyncStructureToUpper;
 | 
			
		||||
				ret.CodeFirst.IsConfigEntityFromDbFirst = _isConfigEntityFromDbFirst;
 | 
			
		||||
@@ -157,73 +157,39 @@ namespace FreeSql {
 | 
			
		||||
				ado.AopCommandExecuting += _aopCommandExecuting;
 | 
			
		||||
				ado.AopCommandExecuted += _aopCommandExecuted;
 | 
			
		||||
 | 
			
		||||
                //添加实体属性名全局AOP转换处理
 | 
			
		||||
                if (_entityPropertyConvertType != StringConvertType.None)
 | 
			
		||||
                {
 | 
			
		||||
                    // 局部方法判断是否存在Column特性以及是否设置Name的值
 | 
			
		||||
                    bool CheckEntityPropertyColumnAttribute(PropertyInfo propertyInfo)
 | 
			
		||||
                    {
 | 
			
		||||
                        var attr = propertyInfo.GetCustomAttribute<ColumnAttribute>();
 | 
			
		||||
                        if (attr == null || string.IsNullOrEmpty(attr.Name))
 | 
			
		||||
                        {
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    switch (_entityPropertyConvertType)
 | 
			
		||||
                    {
 | 
			
		||||
                        case StringConvertType.Lower:
 | 
			
		||||
                            ret.Aop.ConfigEntityProperty = (s, e) =>
 | 
			
		||||
                            {
 | 
			
		||||
                                if (CheckEntityPropertyColumnAttribute(e.Property))
 | 
			
		||||
                                {
 | 
			
		||||
                                    e.ModifyResult.Name = e.Property.Name.ToLower();
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            break;
 | 
			
		||||
                        case StringConvertType.Upper:
 | 
			
		||||
                            ret.Aop.ConfigEntityProperty = (s, e) =>
 | 
			
		||||
                            {
 | 
			
		||||
                                if (CheckEntityPropertyColumnAttribute(e.Property))
 | 
			
		||||
                                {
 | 
			
		||||
                                    e.ModifyResult.Name = e.Property.Name.ToUpper();
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            break;
 | 
			
		||||
                        case StringConvertType.PascalCaseToUnderscore:
 | 
			
		||||
                            ret.Aop.ConfigEntityProperty = (s, e) =>
 | 
			
		||||
                            {
 | 
			
		||||
                                if (CheckEntityPropertyColumnAttribute(e.Property))
 | 
			
		||||
                                {
 | 
			
		||||
                                    e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name);
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            break;
 | 
			
		||||
                        case StringConvertType.PascalCaseToUnderscoreWithLower:
 | 
			
		||||
                            ret.Aop.ConfigEntityProperty = (s, e) =>
 | 
			
		||||
                            {
 | 
			
		||||
                                if (CheckEntityPropertyColumnAttribute(e.Property))
 | 
			
		||||
                                {
 | 
			
		||||
                                    e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower();
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            break;
 | 
			
		||||
                        case StringConvertType.PascalCaseToUnderscoreWithUpper:
 | 
			
		||||
                            ret.Aop.ConfigEntityProperty = (s, e) =>
 | 
			
		||||
                            {
 | 
			
		||||
                                if (CheckEntityPropertyColumnAttribute(e.Property))
 | 
			
		||||
                                {
 | 
			
		||||
                                    e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper();
 | 
			
		||||
                                }
 | 
			
		||||
                            };
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
				//添加实体属性名全局AOP转换处理
 | 
			
		||||
				if (_entityPropertyConvertType != StringConvertType.None) {
 | 
			
		||||
					switch (_entityPropertyConvertType) {
 | 
			
		||||
						case StringConvertType.Lower:
 | 
			
		||||
							ret.Aop.ConfigEntityProperty = (s, e) => {
 | 
			
		||||
								e.ModifyResult.Name = e.Property.Name.ToLower();
 | 
			
		||||
							};
 | 
			
		||||
							break;
 | 
			
		||||
						case StringConvertType.Upper:
 | 
			
		||||
							ret.Aop.ConfigEntityProperty = (s, e) => {
 | 
			
		||||
								e.ModifyResult.Name = e.Property.Name.ToUpper();
 | 
			
		||||
							};
 | 
			
		||||
							break;
 | 
			
		||||
						case StringConvertType.PascalCaseToUnderscore:
 | 
			
		||||
							ret.Aop.ConfigEntityProperty = (s, e) => {
 | 
			
		||||
								e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name);
 | 
			
		||||
							};
 | 
			
		||||
							break;
 | 
			
		||||
						case StringConvertType.PascalCaseToUnderscoreWithLower:
 | 
			
		||||
							ret.Aop.ConfigEntityProperty = (s, e) => {
 | 
			
		||||
								e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToLower();
 | 
			
		||||
							};
 | 
			
		||||
							break;
 | 
			
		||||
						case StringConvertType.PascalCaseToUnderscoreWithUpper:
 | 
			
		||||
							ret.Aop.ConfigEntityProperty = (s, e) => {
 | 
			
		||||
								e.ModifyResult.Name = StringUtils.PascalCaseToUnderScore(e.Property.Name).ToUpper();
 | 
			
		||||
							};
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return ret;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -45,9 +45,9 @@ namespace FreeSql.Internal.CommonProvider {
 | 
			
		||||
		internal ConcurrentDictionary<string, bool> dicSyced = new ConcurrentDictionary<string, bool>();
 | 
			
		||||
		public bool SyncStructure<TEntity>() => this.SyncStructure(typeof(TEntity));
 | 
			
		||||
		public bool SyncStructure(params Type[] entityTypes) {
 | 
			
		||||
			if (entityTypes == null) return true;
 | 
			
		||||
			var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false).ToArray();
 | 
			
		||||
			if (syncTypes.Any() == false) return true;
 | 
			
		||||
			if (entityTypes == null) return false;
 | 
			
		||||
			var syncTypes = entityTypes.Where(a => dicSyced.ContainsKey(a.FullName) == false && GetTableByEntity(a)?.DisableSyncStructure == false).ToArray();
 | 
			
		||||
			if (syncTypes.Any() == false) return false;
 | 
			
		||||
			var before = new Aop.SyncStructureBeforeEventArgs(entityTypes);
 | 
			
		||||
			_orm.Aop.SyncStructureBefore?.Invoke(this, before);
 | 
			
		||||
			Exception exception = null;
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,8 @@ namespace FreeSql.Internal {
 | 
			
		||||
				if (!string.IsNullOrEmpty(trytb.Name)) attr.Name = trytb.Name;
 | 
			
		||||
				if (!string.IsNullOrEmpty(trytb.OldName)) attr.OldName = trytb.OldName;
 | 
			
		||||
				if (!string.IsNullOrEmpty(trytb.SelectFilter)) attr.SelectFilter = trytb.SelectFilter;
 | 
			
		||||
				if (trytb._DisableSyncStructure != null) attr._DisableSyncStructure = trytb.DisableSyncStructure;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			var attrs = type.GetCustomAttributes(typeof(TableAttribute), false);
 | 
			
		||||
			foreach (var tryattrobj in attrs) {
 | 
			
		||||
@@ -81,10 +83,12 @@ namespace FreeSql.Internal {
 | 
			
		||||
				if (!string.IsNullOrEmpty(tryattr.Name)) attr.Name = tryattr.Name;
 | 
			
		||||
				if (!string.IsNullOrEmpty(tryattr.OldName)) attr.OldName = tryattr.OldName;
 | 
			
		||||
				if (!string.IsNullOrEmpty(tryattr.SelectFilter)) attr.SelectFilter = tryattr.SelectFilter;
 | 
			
		||||
				if (tryattr._DisableSyncStructure != null) attr._DisableSyncStructure = tryattr.DisableSyncStructure;
 | 
			
		||||
			}
 | 
			
		||||
			if (!string.IsNullOrEmpty(attr.Name)) return attr;
 | 
			
		||||
			if (!string.IsNullOrEmpty(attr.OldName)) return attr;
 | 
			
		||||
			if (!string.IsNullOrEmpty(attr.SelectFilter)) return attr;
 | 
			
		||||
			if (attr._DisableSyncStructure != null) return attr;
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		public ColumnAttribute GetEntityColumnAttribute(Type type, PropertyInfo proto) {
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ namespace FreeSql.Internal.Model {
 | 
			
		||||
		public string DbName { get; set; }
 | 
			
		||||
		public string DbOldName { get; set; }
 | 
			
		||||
		public string SelectFilter { get; set; }
 | 
			
		||||
		public bool DisableSyncStructure { get; set; }
 | 
			
		||||
 | 
			
		||||
		public ColumnInfo VersionColumn { get; set; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,7 @@ namespace FreeSql.Internal {
 | 
			
		||||
				trytb.DbOldName = trytb.DbOldName?.ToUpper();
 | 
			
		||||
			}
 | 
			
		||||
			trytb.SelectFilter = tbattr?.SelectFilter;
 | 
			
		||||
			if (tbattr != null) trytb.DisableSyncStructure = tbattr.DisableSyncStructure;
 | 
			
		||||
			var propsLazy = new List<(PropertyInfo, bool, bool)>();
 | 
			
		||||
			var propsNavObjs = new List<PropertyInfo>();
 | 
			
		||||
			foreach (var p in trytb.Properties.Values) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user