EF Core - Navigation Properties naming in scaffolding

entity-framework-core

Question

For a really big client I need to create a new architecture and the processes to develop that architecture. I need to use a Database first Strategy and scaffolding from database for every modification.

But the scafolding names for one to one navigation properties are really confusing because it uses the column name instead of the table related.

I have a foreign key in the Invoice table to the product table. The column name IdProduct will give a navigation property named IdProductNavigation

    public Product IdProductNavigation { get; set; }

I understand that it may have been done this way because there can be multiple foreign keys to the same table. In Ef 6 or before the navigation properties were named Products and then Products_1, Products_2, ...

Please can someone tell me How can I give a name to this navigation Property ? I cannot rename the columns but Is there a way to configure the scafolding or maybe to comments the columns or the foreign keys in the database to modify the scaffolding ?

Thank you for your time

1
3
5/31/2018 12:42:27 PM

Popular Answer

You can personalize the Naming of the Navigation Properties adding your own Service to the scaffold.

Create a Class in the Startup Project of your scaffold that extends IDesignTimeServices and a Service for ICandidateNamingService. Example: 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>();
    }
}

Now create the CustomCandidateNamingService.cs class by extending CandidateNamingService In my example i decided to use the DefaultName of the ForeignKey with in my case (SQL Server) is allways FK_TableA_TableB_Field1_Field2, so i delete the FK_ and the Table Name of the actual Table.

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);
        }


    }
}

Attention: I use the Microsoft.EntityFrameworkCore.Scaffolding.Internal Internal API. This can change in future without notice.

2
12/29/2019 8:45:36 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow