mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 优化 FluentApi 继承关系可直接 ConfigEntity<BaseEntity> 生效;#1144
This commit is contained in:
		@@ -849,7 +849,7 @@ FROM [tb_topic22] a", subquery);
 | 
			
		||||
            });
 | 
			
		||||
            Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, isnull((SELECT min(b.[Id]) 
 | 
			
		||||
    FROM [tb_topic22] b), 0) as6, isnull((SELECT min(b.[CreateTime]) 
 | 
			
		||||
    FROM [tb_topic22] b), '1970-01-01 00:00:00.000') as7 
 | 
			
		||||
    FROM [tb_topic22] b), '1970-01-01 00:00:00') as7 
 | 
			
		||||
FROM [tb_topic22] a", subquery);
 | 
			
		||||
            var subqueryList = select.ToList(a => new
 | 
			
		||||
            {
 | 
			
		||||
@@ -869,7 +869,7 @@ FROM [tb_topic22] a", subquery);
 | 
			
		||||
            });
 | 
			
		||||
            Assert.Equal(@"SELECT a.[Id] as1, a.[Clicks] as2, a.[TypeGuid] as3, a.[Title] as4, a.[CreateTime] as5, isnull((SELECT max(b.[Id]) 
 | 
			
		||||
    FROM [tb_topic22] b), 0) as6, isnull((SELECT max(b.[CreateTime]) 
 | 
			
		||||
    FROM [tb_topic22] b), '1970-01-01 00:00:00.000') as7 
 | 
			
		||||
    FROM [tb_topic22] b), '1970-01-01 00:00:00') as7 
 | 
			
		||||
FROM [tb_topic22] a", subquery);
 | 
			
		||||
            var subqueryList = select.ToList(a => new
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
using FreeSql.DataAnnotations;
 | 
			
		||||
using FreeSql.DataAnnotations;
 | 
			
		||||
using FreeSql.Internal;
 | 
			
		||||
using FreeSql.Internal.Model;
 | 
			
		||||
using MySql.Data.MySqlClient;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
@@ -54,6 +56,37 @@ namespace FreeSql.Tests.DataAnnotations
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var tsql1 = g.mysql.Select<ModelAopConfigEntity>().WhereDynamic(1).ToSql();
 | 
			
		||||
 | 
			
		||||
            using (var fsql = new FreeSql.FreeSqlBuilder()
 | 
			
		||||
                .UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=:memory:")
 | 
			
		||||
                .UseAutoSyncStructure(true)
 | 
			
		||||
                .UseMappingPriority(MappingPriorityType.Attribute, MappingPriorityType.Aop, MappingPriorityType.FluentApi)
 | 
			
		||||
                .Build())
 | 
			
		||||
            {
 | 
			
		||||
                ColumnInfo localFunc1() => fsql.CodeFirst.GetTableByEntity(typeof(ModelAopConfigEntity01)).Columns["CreatedTime"];
 | 
			
		||||
                ColumnInfo localFunc2() => fsql.CodeFirst.GetTableByEntity(typeof(ModelAopConfigEntity02)).Columns["CreatedTime"];
 | 
			
		||||
 | 
			
		||||
                Assert.Equal(DateTimeKind.Local, localFunc1().Attribute.ServerTime);
 | 
			
		||||
                Assert.Equal(DateTimeKind.Local, localFunc2().Attribute.ServerTime);
 | 
			
		||||
 | 
			
		||||
                fsql.CodeFirst.ConfigEntity<ModelAopConfigEntityBase>(a => a.Property(b => b.CreatedTime).ServerTime(DateTimeKind.Utc));
 | 
			
		||||
                Assert.Equal(DateTimeKind.Utc, localFunc1().Attribute.ServerTime);
 | 
			
		||||
                Assert.Equal(DateTimeKind.Utc, localFunc2().Attribute.ServerTime);
 | 
			
		||||
 | 
			
		||||
                fsql.CodeFirst.ConfigEntity<ModelAopConfigEntityBase>(a => a.Property(b => b.CreatedTime).ServerTime(DateTimeKind.Local));
 | 
			
		||||
                Assert.Equal(DateTimeKind.Local, localFunc1().Attribute.ServerTime);
 | 
			
		||||
                Assert.Equal(DateTimeKind.Local, localFunc2().Attribute.ServerTime);
 | 
			
		||||
 | 
			
		||||
                fsql.CodeFirst.ConfigEntity<ModelAopConfigEntity01>(a => a.Property(b => b.CreatedTime).ServerTime(DateTimeKind.Utc));
 | 
			
		||||
                Assert.Equal(DateTimeKind.Utc, localFunc1().Attribute.ServerTime);
 | 
			
		||||
 | 
			
		||||
                fsql.CodeFirst.ConfigEntity<ModelAopConfigEntity02>(a => a.Property(b => b.CreatedTime).ServerTime(DateTimeKind.Utc));
 | 
			
		||||
                Assert.Equal(DateTimeKind.Utc, localFunc2().Attribute.ServerTime);
 | 
			
		||||
 | 
			
		||||
                fsql.CodeFirst.ConfigEntity<ModelAopConfigEntityBase>(a => a.Property(b => b.CreatedTime).ServerTime(DateTimeKind.Local));
 | 
			
		||||
                Assert.Equal(DateTimeKind.Utc, localFunc1().Attribute.ServerTime);
 | 
			
		||||
                Assert.Equal(DateTimeKind.Utc, localFunc2().Attribute.ServerTime);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        [System.ComponentModel.DataAnnotations.Schema.Table("xxx")]
 | 
			
		||||
        class ModelAopConfigEntity
 | 
			
		||||
@@ -62,6 +95,17 @@ namespace FreeSql.Tests.DataAnnotations
 | 
			
		||||
            [Column(IsPrimary = false)]
 | 
			
		||||
            public int pkid { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
        class ModelAopConfigEntityBase
 | 
			
		||||
        {
 | 
			
		||||
            [Column(CanUpdate = false, ServerTime = DateTimeKind.Local)]
 | 
			
		||||
            public virtual DateTime CreatedTime { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
        class ModelAopConfigEntity01 : ModelAopConfigEntityBase
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        class ModelAopConfigEntity02 : ModelAopConfigEntityBase
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Fluent()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
using FreeSql.DataAnnotations;
 | 
			
		||||
using FreeSql.DataAnnotations;
 | 
			
		||||
using FreeSql.Tests.DataContext.SqlServer;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
@@ -50,7 +50,7 @@ namespace FreeSql.Tests.DataAnnotations
 | 
			
		||||
                {
 | 
			
		||||
                    a.Name("xxdkdkdk1222");
 | 
			
		||||
                    a.Property("Id").Name("Id22dd").IsIdentity(true);
 | 
			
		||||
                    a.Property("Name").DbType("varchar(101)").IsNullable(true);
 | 
			
		||||
                    a.Property("Name").Name("Name").DbType("varchar(101)").IsNullable(true);
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                .ConfigEntity<TestFluenttb2>(a =>
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ namespace FreeSql.DataAnnotations
 | 
			
		||||
        public ColumnFluent Property(string proto)
 | 
			
		||||
        {
 | 
			
		||||
            if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException(CoreStrings.NotFound_PropertyName(proto));
 | 
			
		||||
            var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto });
 | 
			
		||||
            var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { });
 | 
			
		||||
            return new ColumnFluent(col, tryProto, _entityType);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -136,7 +136,7 @@ namespace FreeSql.DataAnnotations
 | 
			
		||||
        public ColumnFluent Property(string proto)
 | 
			
		||||
        {
 | 
			
		||||
            if (_properties.TryGetValue(proto, out var tryProto) == false) throw new KeyNotFoundException(CoreStrings.NotFound_PropertyName(proto));
 | 
			
		||||
            var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { Name = proto });
 | 
			
		||||
            var col = _table._columns.GetOrAdd(tryProto.Name, name => new ColumnAttribute { });
 | 
			
		||||
            return new ColumnFluent(col, tryProto, typeof(T));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3724,192 +3724,205 @@
 | 
			
		||||
            状态数据,可与 CommandAfter 共享
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.CommandAfterEventArgs.Exception">
 | 
			
		||||
            <summary>
 | 
			
		||||
            发生的错误
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.CommandAfterEventArgs.Log">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行SQL命令,返回的结果
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.CommandAfterEventArgs.ElapsedTicks">
 | 
			
		||||
            <summary>
 | 
			
		||||
            耗时(单位:Ticks)
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.CommandAfterEventArgs.ElapsedMilliseconds">
 | 
			
		||||
            <summary>
 | 
			
		||||
            耗时(单位:毫秒)
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.TraceBeforeEventArgs.Identifier">
 | 
			
		||||
            <summary>
 | 
			
		||||
            标识符,可将 TraceBeforeEventArgs 与 TraceAfterEventArgs 进行匹配
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.TraceBeforeEventArgs.States">
 | 
			
		||||
            <summary>
 | 
			
		||||
            状态数据,可与 TraceAfter 共享
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.TraceAfterEventArgs.Remark">
 | 
			
		||||
            <summary>
 | 
			
		||||
            备注
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.TraceAfterEventArgs.Exception">
 | 
			
		||||
            <summary>
 | 
			
		||||
            发生的错误
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.TraceAfterEventArgs.ElapsedTicks">
 | 
			
		||||
            <summary>
 | 
			
		||||
            耗时(单位:Ticks)
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Aop.TraceAfterEventArgs.ElapsedMilliseconds">
 | 
			
		||||
            <summary>
 | 
			
		||||
            耗时(单位:毫秒)
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsAutoSyncStructure">
 | 
			
		||||
            <summary>
 | 
			
		||||
            【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsSyncStructureToLower">
 | 
			
		||||
            <summary>
 | 
			
		||||
            转小写同步结构,适用 PostgreSQL
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsSyncStructureToUpper">
 | 
			
		||||
            <summary>
 | 
			
		||||
            转大写同步结构,适用 Oracle/达梦/人大金仓
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsConfigEntityFromDbFirst">
 | 
			
		||||
            <summary>
 | 
			
		||||
            将数据库的主键、自增、索引设置导入,适用 DbFirst 模式,无须在实体类型上设置 [Column(IsPrimary)] 或者 ConfigEntity。此功能目前可用于 mysql/sqlserver/postgresql/oracle。<para></para>
 | 
			
		||||
            本功能会影响 IFreeSql 首次访问的速度。<para></para>
 | 
			
		||||
            若使用 CodeFirst 创建索引后,又直接在数据库上建了索引,若无本功能下一次 CodeFirst 迁移时数据库上创建的索引将被删除
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsNoneCommandParameter">
 | 
			
		||||
            <summary>
 | 
			
		||||
            不使用命令参数化执行,针对 Insert/Update
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsGenerateCommandParameterWithLambda">
 | 
			
		||||
            <summary>
 | 
			
		||||
            是否生成命令参数化执行,针对 lambda 表达式解析<para></para>
 | 
			
		||||
            注意:常量不会参数化,变量才会做参数化<para></para>
 | 
			
		||||
            var id = 100;
 | 
			
		||||
            fsql.Select<T>().Where(a => a.id == id) 会参数化<para></para>
 | 
			
		||||
            fsql.Select<T>().Where(a => a.id == 100) 不会参数化
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.ICodeFirst.IsLazyLoading">
 | 
			
		||||
            <summary>
 | 
			
		||||
            延时加载导航属性对象,导航属性需要声明 virtual
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetComparisonDDLStatements``1">
 | 
			
		||||
            <summary>
 | 
			
		||||
            将实体类型与数据库对比,返回DDL语句
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="TEntity"></typeparam>
 | 
			
		||||
        <member name="P:FreeSql.A
 | 
			
		||||
            <param name="column"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetComparisonDDLStatements(System.Type[])">
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetCsType(FreeSql.DatabaseModel.DbColumnInfo)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            将实体类型集合与数据库对比,返回DDL语句
 | 
			
		||||
            获取c#类型,int、long
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityTypes">实体类型</param>
 | 
			
		||||
            <param name="column"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetComparisonDDLStatements(System.Type,System.String)">
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetCsTypeInfo(FreeSql.DatabaseModel.DbColumnInfo)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            将实体类型与数据库对比,返回DDL语句(指定表名)
 | 
			
		||||
            获取c#类型对象
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityType">实体类型</param>
 | 
			
		||||
            <param name="tableName">指定表名对比</param>
 | 
			
		||||
            <param name="column"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.SyncStructure``1">
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetDataReaderMethod(FreeSql.DatabaseModel.DbColumnInfo)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            同步实体类型到数据库<para></para>
 | 
			
		||||
            注意:生产环境中谨慎使用
 | 
			
		||||
            获取ado.net读取方法, GetBoolean、GetInt64
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="TEntity"></typeparam>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.SyncStructure(System.Type[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            同步实体类型集合到数据库<para></para>
 | 
			
		||||
            注意:生产环境中谨慎使用
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityTypes"></param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.SyncStructure(System.Type,System.String,System.Boolean)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            同步实体类型到数据库(指定表名)<para></para>
 | 
			
		||||
            注意:生产环境中谨慎使用
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="entityType">实体类型</param>
 | 
			
		||||
            <param name="tableName">指定表名对比</param>
 | 
			
		||||
            <param name="isForceSync">强制同步结构,无视缓存每次都同步</param>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetDbInfo(System.Type)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            根据 System.Type 获取数据库信息
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="type"></param>
 | 
			
		||||
            <param name="column"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.ConfigEntity``1(System.Action{FreeSql.DataAnnotations.TableFluent{``0}})">
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetCsStringify(FreeSql.DatabaseModel.DbColumnInfo)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            FreeSql FluentApi 配置实体,方法名与特性相同
 | 
			
		||||
            序列化
 | 
			
		||||
            </summary>
 | 
			
		||||
            <typeparam name="T"></typeparam>
 | 
			
		||||
            <param name="entity"></param>
 | 
			
		||||
            <param name="column"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.ConfigEntity(System.Type,System.Action{FreeSql.DataAnnotations.TableFluent})">
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetCsParse(FreeSql.DatabaseModel.DbColumnInfo)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            FreeSql FluentApi 配置实体,方法名与特性相同
 | 
			
		||||
            反序列化
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="type"></param>
 | 
			
		||||
            <param name="entity"></param>
 | 
			
		||||
            <param name="column"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetConfigEntity(System.Type)">
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetEnumsByDatabase(System.String[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            获取 FreeSql FluentApi 配置实体的元数据
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="type"></param>
 | 
			
		||||
            <returns>未使用ConfigEntity配置时,返回null</returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.ICodeFirst.GetTableByEntity(System.Type)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            获取实体类核心配置
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="type"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetDatabases">
 | 
			
		||||
            <summary>
 | 
			
		||||
            获取所有数据库
 | 
			
		||||
            </summary>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetTablesByDatabase(System.String[])">
 | 
			
		||||
            <summary>
 | 
			
		||||
            获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键、备注
 | 
			
		||||
            获取数据库枚举类型,适用 PostgreSQL
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="database"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="F:FreeSql.Internal.BaseDiyMemberExpression._lambdaParameter">
 | 
			
		||||
            <summary>
 | 
			
		||||
            临时 LambdaExpression.Parameter
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.Internal.CommonProvider.InsertOrUpdateProvider`1.SplitSourceByIdentityValueIsNull(System.Collections.Generic.List{`0})">
 | 
			
		||||
            <summary>
 | 
			
		||||
            如果实体类有自增属性,分成两个 List,有值的Item1 merge,无值的Item2 insert
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="source"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.Internal.CommonProvider.InsertProvider`1.IgnoreCanInsert">
 | 
			
		||||
            <summary>
 | 
			
		||||
            AsType, Ctor, ClearData 三处地方需要重新加载
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.Internal.CommonProvider.UpdateProvider`1.IgnoreCanUpdate">
 | 
			
		||||
            <summary>
 | 
			
		||||
            AsType, Ctor, ClearData 三处地方需要重新加载
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.Internal.CommonUtils.GetPropertyCommentByDescriptionAttribute(System.Type)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            动态读取 DescriptionAttribute 注释文本
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="type"></param>
 | 
			
		||||
            <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.Internal.CommonUtils.GetProperyCommentBySummary(System.Type)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            通过属性的注释文本,通过 xml 读取
 | 
			
		||||
            </summary>
 | 
			
		||||
            <param name="type"></param>
 | 
			
		||||
            <returns>Dict:key=属性名,value=注释</returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Internal.DbUpdateVersionException.Table">
 | 
			
		||||
            <summary>
 | 
			
		||||
            更新实体的元数据
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Internal.DbUpdateVersionException.Sql">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行更新的 SQL
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Internal.DbUpdateVersionException.DbParams">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行更新命令的参数
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Internal.DbUpdateVersionException.Affrows">
 | 
			
		||||
            <summary>
 | 
			
		||||
            执行更新命令影响的行
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Internal.DbUpdateVersionException.EntitySourceCount">
 | 
			
		||||
            <summary>
 | 
			
		||||
            更新的实体数量
 | 
			
		||||
            </summary>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="P:FreeSql.Internal.DbUpdateVersionException.EntitySource">
 | 
			
		||||
            <summary>
 | 
			
		||||
            更新的实体
 | 
			
		||||
            </summary>
 | 
			
		||||
        </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.PascalCaseToUnderscoreWithLow         <returns></returns>
 | 
			
		||||
        </member>
 | 
			
		||||
        <member name="M:FreeSql.IDbFirst.GetTableByName(System.String,System.Boolean)">
 | 
			
		||||
            <summary>
 | 
			
		||||
            获取指定单表信息,包括列详情、主键、唯一键、索引、备注
 | 
			
		||||
 
 | 
			
		||||
@@ -196,27 +196,38 @@ namespace FreeSql.Internal
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    case MappingPriorityType.FluentApi:
 | 
			
		||||
                        if (dicConfigEntity.TryGetValue(type, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol))
 | 
			
		||||
                        var baseTypes = new List<Type>();
 | 
			
		||||
                        var baseType = type;
 | 
			
		||||
                        while (baseType != typeof(object) && baseType != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name;
 | 
			
		||||
                            if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName;
 | 
			
		||||
                            if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType;
 | 
			
		||||
                            if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary;
 | 
			
		||||
                            if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity;
 | 
			
		||||
                            if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable;
 | 
			
		||||
                            if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore;
 | 
			
		||||
                            if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion;
 | 
			
		||||
                            if (trycol.MapType != null) attr.MapType = trycol.MapType;
 | 
			
		||||
                            if (trycol._Position != null) attr._Position = trycol.Position;
 | 
			
		||||
                            if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert;
 | 
			
		||||
                            if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate;
 | 
			
		||||
                            if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime;
 | 
			
		||||
                            if (trycol._StringLength != null) attr.StringLength = trycol.StringLength;
 | 
			
		||||
                            if (!string.IsNullOrEmpty(trycol.InsertValueSql)) attr.InsertValueSql = trycol.InsertValueSql;
 | 
			
		||||
                            if (trycol._Precision != null) attr.Precision = trycol.Precision;
 | 
			
		||||
                            if (trycol._Scale != null) attr.Scale = trycol.Scale;
 | 
			
		||||
                            if (!string.IsNullOrEmpty(trycol.RewriteSql)) attr.RewriteSql = trycol.RewriteSql;
 | 
			
		||||
                            if (!string.IsNullOrEmpty(trycol.RereadSql)) attr.RereadSql = trycol.RereadSql;
 | 
			
		||||
                            baseTypes.Add(baseType);
 | 
			
		||||
                            baseType = baseType.BaseType;
 | 
			
		||||
                        }
 | 
			
		||||
                        for (var a = baseTypes.Count - 1; a >= 0; a--)
 | 
			
		||||
                        {
 | 
			
		||||
                            var entityType = baseTypes[a];
 | 
			
		||||
                            if (dicConfigEntity.TryGetValue(entityType, out var trytb) && trytb._columns.TryGetValue(proto.Name, out var trycol))
 | 
			
		||||
                            {
 | 
			
		||||
                                if (!string.IsNullOrEmpty(trycol.Name)) attr.Name = trycol.Name;
 | 
			
		||||
                                if (!string.IsNullOrEmpty(trycol.OldName)) attr.OldName = trycol.OldName;
 | 
			
		||||
                                if (!string.IsNullOrEmpty(trycol.DbType)) attr.DbType = trycol.DbType;
 | 
			
		||||
                                if (trycol._IsPrimary != null) attr._IsPrimary = trycol.IsPrimary;
 | 
			
		||||
                                if (trycol._IsIdentity != null) attr._IsIdentity = trycol.IsIdentity;
 | 
			
		||||
                                if (trycol._IsNullable != null) attr._IsNullable = trycol.IsNullable;
 | 
			
		||||
                                if (trycol._IsIgnore != null) attr._IsIgnore = trycol.IsIgnore;
 | 
			
		||||
                                if (trycol._IsVersion != null) attr._IsVersion = trycol.IsVersion;
 | 
			
		||||
                                if (trycol.MapType != null) attr.MapType = trycol.MapType;
 | 
			
		||||
                                if (trycol._Position != null) attr._Position = trycol.Position;
 | 
			
		||||
                                if (trycol._CanInsert != null) attr._CanInsert = trycol.CanInsert;
 | 
			
		||||
                                if (trycol._CanUpdate != null) attr._CanUpdate = trycol.CanUpdate;
 | 
			
		||||
                                if (trycol.ServerTime != DateTimeKind.Unspecified) attr.ServerTime = trycol.ServerTime;
 | 
			
		||||
                                if (trycol._StringLength != null) attr.StringLength = trycol.StringLength;
 | 
			
		||||
                                if (!string.IsNullOrEmpty(trycol.InsertValueSql)) attr.InsertValueSql = trycol.InsertValueSql;
 | 
			
		||||
                                if (trycol._Precision != null) attr.Precision = trycol.Precision;
 | 
			
		||||
                                if (trycol._Scale != null) attr.Scale = trycol.Scale;
 | 
			
		||||
                                if (!string.IsNullOrEmpty(trycol.RewriteSql)) attr.RewriteSql = trycol.RewriteSql;
 | 
			
		||||
                                if (!string.IsNullOrEmpty(trycol.RereadSql)) attr.RereadSql = trycol.RereadSql;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    case MappingPriorityType.Attribute:
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,9 @@ namespace FreeSql.Internal
 | 
			
		||||
                ) return;
 | 
			
		||||
            var tbc = _cacheGetTableByEntity.GetOrAdd(common._orm.Ado.DataType, k1 => new ConcurrentDictionary<Type, TableInfo>()); //区分数据库类型缓存
 | 
			
		||||
            if (tbc.TryRemove(entity, out var trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz);
 | 
			
		||||
            var reltypes = tbc.Keys.Where(a => entity.IsAssignableFrom(a)).ToArray();
 | 
			
		||||
            foreach (var reltype in reltypes)
 | 
			
		||||
                if (tbc.TryRemove(reltype, out trytb) && trytb?.TypeLazy != null) tbc.TryRemove(trytb.TypeLazy, out var trylz);
 | 
			
		||||
        }
 | 
			
		||||
        internal static TableInfo GetTableByEntity(Type entity, CommonUtils common)
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user