FreeSql icon indicating copy to clipboard operation
FreeSql copied to clipboard

fsql.Aop.ConfigEntity 事件中,可以处理表名和索引名,但处理不了OraclePrimaryKeyNameAttribute设定的主键名称。

Open ensleep opened this issue 1 year ago • 1 comments

场景:

1、CodeFirst方式下,FreeSql提供了fsql.Aop.ConfigEntity事件,以修改实体与表名、索引名、主键名的对应关系。 2、由于Oracle对主键名称要求特殊,所以FreeSql提供了oracle专用的OraclePrimaryKeyNameAttribute特性来命名Oracle中对应的主键名称。

问题: 当我使用了fsql.Aop.ConfigEntity事件来修改实体与数据库对象之间的映射关系时,可以完成对表名、索引名称的修改,但是,却无法修改使用OraclePrimaryKeyNameAttribute所指定的Oracle的特定主键名,这应该是设计上的Bug。

影响: 1、当我编写一套自动部署数据库结构的程序时,一个用户空间下只能部署一个,如果想部署多个,即需要借助fsql.Aop.ConfigEntity事件来修改数据库对象的名称以防止多个部署互相冲突。但是,我无法在fsql.Aop.ConfigEntity事件中修改OraclePrimaryKeyNameAttribute的值,导致在Oracle中,表的主键重复,无法实现多个实例的部署。

问题描述及重现代码:

private static void FreeSql_Aop_ConfigEntity(object sender, FreeSql.Aop.ConfigEntityEventArgs e)
{
    if(!string.IsNullOrWhiteSpace(Services.GlobalConfigs.Table_Prefix))
    {

        // 修改索引
        var tp = Services.GlobalConfigs.Table_Prefix;
        var IndexAttrs = e.EntityType.GetCustomAttributes(typeof(IndexAttribute));
        foreach(IndexAttribute idx in IndexAttrs)
        {
            idx.Name = tp + idx.Name;
            e.ModifyIndexResult.Add(idx);
        }
        
        var OPkNameAttrs =(OraclePrimaryKeyNameAttribute) e.EntityType.GetCustomAttributes(typeof(OraclePrimaryKeyNameAttribute));
        if ( OPkNameAttrs != null)
        {
            // 无处修改 OPkNameAttrs中的Name
        }

        // 修改表名
        var TableAttr = (TableAttribute)e.EntityType.GetCustomAttributes(typeof(TableAttribute));
        if (TableAttr == null)
        {
            e.ModifyResult.OldName = tp + e.EntityType.GetType().Name;
        }
        else
        {
            if (!string.IsNullOrWhiteSpace(TableAttr.AsTable))
            {
                e.ModifyResult.AsTable = tp+ TableAttr.AsTable;
            }
            else if(!string.IsNullOrWhiteSpace(TableAttr.Name))
            {
                e.ModifyResult.Name = tp + TableAttr.Name;
            }
            else if (!string.IsNullOrWhiteSpace(TableAttr.OldName))
            {
                e.ModifyResult.OldName = tp + TableAttr.OldName;
            }
            else
            {
                e.ModifyResult.OldName = tp + e.EntityType.GetType().Name;
            }
        }
    }
}

数据库版本

所有版本

安装的Nuget包

<PackageReference Include="FreeSql" Version="3.2.685" />
<PackageReference Include="FreeSql.Extensions.BaseEntity" Version="3.2.685" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.7" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.16.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.7" />
<PackageReference Include="NuGet.Common" Version="6.9.1" />
<PackageReference Include="NuGet.Protocol" Version="6.9.1" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="Oracle.ManagedDataAccess.Core" Version="3.21.100" />
<PackageReference Include="FreeSql.Provider.Oracle" Version="3.2.695" />

.net framework/. net core? 及具体版本

.net core 6.0

ensleep avatar Mar 18 '24 06:03 ensleep

OraclePrimaryKeyNameAttribute 是 oracle 的特殊处理。

如果不使用特性指定主键名,暂时先用 CodeFrst.GetDDLxxx() 方法获取迁移表结构的脚本,然后定位 replace 一下,再使用 Ado 执行,等有空了再处理 fluentapi 。

2881099 avatar Mar 18 '24 08:03 2881099