Entity Framework Core Customize Scaffolding

前端 未结 5 1670
天命终不由人
天命终不由人 2020-12-10 14:19

I have done scaffolding of my SQLServer database. And it creates the POCO objects in the specified folder. What i would like to do is that it extends from my base class. I a

5条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-10 14:23

    In my scenario I wanted to prefix all table names with an underscore. Version: Core 2.2.
    I don't use Id as name of my primary key column, instead table name + Id like this: FoodId. This forced me to add the [Key] data annotation to the primary key.


    Model
    Scaffold Model Example:

    using System;
    using System.Collections.Generic;
    
    namespace MyNamespace
    {
        public partial class Food
        {
             public int FoodId { get; set; }
             public string Name { get; set; }
             public string Description { get; set; }
             public double Price { get; set; }
        }
    }
    

    Expected Result:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations; //Add
    
    namespace MyNamespace
    {
        public partial class _Food //Prefix with underscore
        {
             [Key] //Add
             public int FoodId { get; set; }
             public string Name { get; set; }
             public string Description { get; set; }
             public double Price { get; set; }
        }
    }
    


    How I solved it
    I used a combination of @Chris Peacock's and @DavidC's answers.

    1. Firstly, rename all entities
    To prevent renaming of properties I had to explicitly tell which unique identifiers to rename, because Uniquifier function doesn't tell which type it renames.

    public class MyCSharpUtilities : CSharpUtilities
    {
        public override string Uniquifier(string proposedIdentifier, ICollection existingIdentifiers)
        {
            var finalIdentifier = base.Uniquifier(proposedIdentifier, existingIdentifiers);
    
            //Prefix entity names with underscore
            if (finalIdentifier == "Food" ||
                finalIdentifier == "Fruit" ||
                finalIdentifier == "Vegetables")
            {
                finalIdentifier = "_" + finalIdentifier;
            }
    
            return finalIdentifier;
        }
    }
    

    2. Secondly, add the using statement and the [Key]

    public class MyEntityTypeGenerator : CSharpEntityTypeGenerator
    {
        public MyEntityTypeGenerator(ICSharpHelper cSharpHelper) : base(cSharpHelper) { }   
    
        public override string WriteCode(IEntityType entityType, string @namespace, bool useDataAnnotations)
        {
            string code = base.WriteCode(entityType, @namespace, useDataAnnotations);           
            string entityTypeName = entityType.Name.Replace("_", "");
            string keyPropertyString = "public int " + entityTypeName + "Id { get; set; }";
    
            if (code.Contains(keyPropertyString))
            {
                //Add "using" for data annotation
                string oldString = "using System.Collections.Generic;" + Environment.NewLine + Environment.NewLine + "namespace MyNamespace";
                string newString = "using System.Collections.Generic;" + Environment.NewLine + "using System.ComponentModel.DataAnnotations;" + Environment.NewLine + Environment.NewLine + "namespace MyNamespace";
                code = code.Replace(oldString, newString);
    
                //Add [Key] data annotation
                string newKeyPropertyString = "[Key]" + Environment.NewLine + "\t\t" + keyPropertyString;
                code = code.Replace(keyPropertyString, newKeyPropertyString);
            }
    
            return code;
        }
    }
    

    3. Finally, add these services to Startup.cs

    public class CustomEFDesignTimeServices : IDesignTimeServices
    {
        //Used for scaffolding database to code
        public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
        {
            serviceCollection.AddSingleton();
            serviceCollection.AddSingleton();
        }
    }
    

提交回复
热议问题