为啥我的 Entity Framework Core Database-First 模型自定义更改在 Re-Scaffold 后消失了?任何解决方案

Posted

技术标签:

【中文标题】为啥我的 Entity Framework Core Database-First 模型自定义更改在 Re-Scaffold 后消失了?任何解决方案【英文标题】:Why my Entity Framework Core Database-First Model Custom Changes Gone After Re-Scaffold? Any Solution为什么我的 Entity Framework Core Database-First 模型自定义更改在 Re-Scaffold 后消失了?任何解决方案 【发布时间】:2021-02-17 02:54:30 【问题描述】:

我正在使用 ASP.Net Core 2.1,但遇到了问题。我一直在努力实现一个 Database-First 应用程序。最初的 Scaffold-DbContext 命令可以正常工作并正确创建我的所有实体。之后,我对模型文件进行了一些更改以进行验证。我的 DBA 对 DB 进行了新的更改,所以我重新搭建了 DB。然后我注意到 re-scaffold 会覆盖我添加到所有模型文件中的所有自定义代码。 我有什么方法可以重新搭建数据库,但只会更改 DBA 在 ASP.Net Core DB First Approach 中更改的那些文件? 每次我都面临这个问题。 我使用以下命令重新搭建脚手架:

Scaffold-DbContext "Server=192.168.46.101;Database=DBNAME;User Id=USERID;Password=PASSWORD" Microsoft.EntityFrameworkCore.SqlServer -ContextDir Data -OutputDir Models -UseDatabaseNames -force

我为模型添加的自定义注释:

    //Custom Annotation
    [Key]
    public int COLORCODE  get; set; 

    //Custom Validation
    [Required(ErrorMessage = "Color Name can not be empty")]
    public string COLOR  get; set; 

    public string REMARKS  get; set; 

重新搭建后我的代码如下:

    public int COLORCODE  get; set; 
    public string COLOR  get; set; 
    public string REMARKS  get; set; 

我的 Program.cs 文件:

public class Program

    public static void Main(string[] args)
    
        CreateWebHostBuilder(args).Build().Run();
    

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
                logging.AddDebug();
                logging.AddEventSourceLogger();
                logging.AddNLog();
            )
            .UseStartup<Startup>();

我的 Startup.cs 文件:

public class Startup

    public Startup(IConfiguration configuration)
    
        Configuration = configuration;
    

    public IConfiguration Configuration  get; 

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    

        services.ConfigureApplicationCookie(options =>
        
            options.AccessDeniedPath = new PathString("/Administrator/AccessDenied");
        );

        services.Configure<CookiePolicyOptions>(options =>
        
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            // options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        );

        services.AddDbContext<Context>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("ConnectionName")));


        services.AddIdentity<IdentityUser, IdentityRole>(options =>
        
            options.Password.RequiredLength = 15;
            options.Password.RequiredUniqueChars = 5;
            options.Password.RequireNonAlphanumeric = false;

            options.SignIn.RequireConfirmedEmail = true;
            options.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation";

            options.Lockout.MaxFailedAccessAttempts = 5;
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
        )
        .AddEntityFrameworkStores<Context>()
        .AddDefaultTokenProviders()
        .AddTokenProvider<CustomEmailConfirmationTokenProvider<IdentityUser>>("CustomEmailConfirmation");

        // REGISTER ExtractEMService
        ExtractEMService.ExtractEMRegisterService(services);

        //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddMvc(options =>
        
            var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
            options.Filters.Add(new AuthorizeFilter(policy));

        ).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        
        else
        
            app.UseExceptionHandler("/Error");
            app.UseStatusCodePagesWithReExecute("/Error/0");

            //app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseAuthentication();

        app.UseMvc(routes =>
        
            routes.MapRoute(
                name: "default",
                template: "controller=Basic/action=BasicColors/id?");
        );
    

【问题讨论】:

【参考方案1】:

您无法做到这一点,但只需将生成的类保持原样并使用伙伴类进行数据注释:

[MetadataType(typeof(MetaData))]
public partial class Person

    public class MetaData
    
        [Required]
        [Display(Name = "Enter Your Name")]
        public string FirstName;

      
    

https://ryanhayes.net/data-annotations-for-entity-framework-4-entities-as-an-mvc-model/

【讨论】:

以上是关于为啥我的 Entity Framework Core Database-First 模型自定义更改在 Re-Scaffold 后消失了?任何解决方案的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须为 Code First / Entity Framework 提供无参数构造函数

为啥我的 Entity Framework Core Database-First 模型自定义更改在 Re-Scaffold 后消失了?任何解决方案

为啥运行时表达式会导致 Entity Framework Core 5 的缓存发生冲突?

为啥 Entity framework Entity Master Details Entity Edit

为啥要使用 Attach 来更新 Entity Framework 6?

为啥在我运行迁移时 Entity Framework 包会自动更新?