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

时间:2018-05-31 09:49:29

标签: entity-framework-core

对于一个非常大的客户,我需要创建一个新的架构和开发该架构的流程。我需要使用数据库第一个策略和数据库中的脚手架进行每次修改。

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

我在产品表的Invoice表中有一个外键。列名IdProduct将提供名为IdProductNavigation

的导航属性
    public Product IdProductNavigation { get; set; }

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

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

感谢您的时间

1 个答案:

答案 0 :(得分:1)

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

在您的支架的启动项目中创建一个类,该类扩展了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>();
    }
}

现在通过扩展CandidateNamingService创建CustomCandidateNamingService.cs类 在我的示例中,我决定在所有情况下(SQL Server)始终使用ForeignKey的DefaultName为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);
        }


    }
}

注意:我使用Microsoft.EntityFrameworkCore.Scaffolding.Internal内部API。将来可能会更改,恕不另行通知。