EF Core - 脚手架中的导航属性命名

neo*_*oms 8 entity-framework-core

对于一个真正的大客户,我需要创建一个新的架构和开发该架构的流程。对于每次修改,我都需要使用数据库优先策略和数据库中的脚手架。

但是一对一导航属性的脚架名称确实令人困惑,因为它使用列名而不是相关的表。

我在 Invoice 表中有一个到 product 表的外键。列名 IdProduct 将提供一个名为 IdProductNavigation 的导航属性

    public Product IdProductNavigation { get; set; }
Run Code Online (Sandbox Code Playgroud)

我知道它可能已经这样做了,因为同一个表可以有多个外键。在 Ef 6 或之前,导航属性被命名为 Products,然后是 Products_1、Products_2、...

请有人告诉我如何给这个导航属性命名?我无法重命名列,但是有没有办法配置脚手架,或者可以注释数据库中的列或外键来修改脚手架?

感谢您的时间

小智 6

您可以个性化导航属性的命名,将您自己的服务添加到脚手架中。

在脚手架的启动项目中创建一个类,用于扩展 IDesignTimeServices 和 ICandidateNamingService 的服务。示例:MyEFDesignTimeServices.cs

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using Microsoft.Extensions.DependencyInjection;
using StartProject;
using System;
using System.Collections.Generic;
using System.Text;

public class MyEFDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
    {
        serviceCollection.AddSingleton<ICandidateNamingService, CustomCandidateNamingService>();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在通过扩展 CandidateNamingService 创建 CustomCandidateNamingService.cs 类 在我的示例中,我决定使用外键的 DefaultName,在我的情况下 (SQL Server) 始终是 FK_TableA_TableB_Field1_Field2,因此我删除了 FK_ 和实际表的表名称。

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Scaffolding.Internal;
using System;
using System.Collections.Generic;
using System.Text;

namespace StartProject
{
    public class CustomCandidateNamingService: CandidateNamingService
    {
        public override string GetDependentEndCandidateNavigationPropertyName(IForeignKey foreignKey)
        {
            try
            {
                string newName = foreignKey.GetDefaultName().Replace("FK_", "")
                                           .Replace(foreignKey.DeclaringEntityType.Name + "_", "", StringComparison.OrdinalIgnoreCase);
                return newName;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error in Generating GetDependentEndCandidateNavigationPropertyName: " + ex.Message);
            }

            return base.GetDependentEndCandidateNavigationPropertyName(foreignKey);
        }

        public override string GetPrincipalEndCandidateNavigationPropertyName(IForeignKey foreignKey, string dependentEndNavigationPropertyName)
        {
            try
            {
                string newName = foreignKey.GetDefaultName().Replace("FK_", "")
                                           .Replace(foreignKey.PrincipalEntityType.Name + "_", "", StringComparison.OrdinalIgnoreCase);
                return newName;
            }
            catch(Exception ex) {
                Console.WriteLine("Error in Generating GetPrincipalEndCandidateNavigationPropertyName: " + ex.Message);
            }
            return base.GetPrincipalEndCandidateNavigationPropertyName(foreignKey, dependentEndNavigationPropertyName);
        }


    }
}

Run Code Online (Sandbox Code Playgroud)

注意:我使用 Microsoft.EntityFrameworkCore.Scaffolding.Internal 内部 API。这将来可能会发生变化,恕不另行通知。