You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中EF Core数据库优先Scaffolding时保留数据注解的方法

解决EF Core数据库优先模式下Scaffold后数据注解丢失的问题

针对你遇到的每次执行Scaffold-DbContext后实体类数据注解丢失的问题,有几个比视图模型副本更高效的方案:

1. 用分部类+元数据类型分离注解

EF Core自动生成的实体类默认是分部类,你可以创建一个同名的分部类文件(注意不要和自动生成的.g.cs文件重名),在其中通过MetadataType特性关联元数据类,把所有数据注解放在元数据类里。这样重新Scaffold时,只会覆盖自动生成的分部类文件,你手写的元数据部分完全不受影响。

示例代码:

// 自动生成的Product.g.cs(Scaffold生成,会被覆盖)
public partial class Product
{
    public int Id { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
}

// 你手动创建的Product.cs(不会被Scaffold覆盖)
[MetadataType(typeof(ProductMetadata))]
public partial class Product { }

public class ProductMetadata
{
    [Required(ErrorMessage = "产品名称不能为空")]
    [Display(Name = "产品名称")]
    [StringLength(50, MinimumLength = 2)]
    public string ProductName { get; set; }

    [Range(0.01, 9999.99, ErrorMessage = "价格必须在0.01到9999.99之间")]
    [Display(Name = "产品价格")]
    public decimal Price { get; set; }
}

2. 用Fluent API替代数据注解(EF相关配置)

如果你的注解是和EF Core映射相关的(比如主键、列长度、外键关系等),完全可以把这些配置移到DbContext的OnModelCreating方法中,用Fluent API实现。这样不需要在实体类上添加任何注解,而且可以把自定义配置和自动生成的配置分离:

示例代码:

// 自定义DbContext分部类(不会被Scaffold覆盖)
public partial class AppDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // 自定义配置
        modelBuilder.Entity<Product>(entity =>
        {
            entity.Property(e => e.ProductName)
                .IsRequired()
                .HasMaxLength(50);
            
            entity.Property(e => e.Price)
                .HasColumnType("decimal(18,2)");
        });

        // 调用自动生成的配置(Scaffold会在另一个分部类生成OnModelCreatingPartial方法)
        OnModelCreatingPartial(modelBuilder);
    }
}

执行Scaffold-DbContext时,只要不使用-Force参数覆盖整个DbContext,自定义的Fluent配置就会保留。

3. 自定义Scaffold模板(批量配置场景)

如果需要给所有实体统一添加元数据或注解,可以自定义EF Core的Scaffold T4模板,让生成的代码自动包含你需要的逻辑。步骤如下:

  • 安装EF Core模板包:dotnet new install Microsoft.EntityFrameworkCore.Templates
  • 导出模板到本地目录:dotnet new ef-scaffold-template -o ScaffoldTemplates
  • 修改导出的EntityType.t4模板,添加注解生成逻辑(比如给所有字符串属性默认加StringLength,或者添加Display特性)
  • 执行Scaffold时指定模板目录:Scaffold-DbContext "你的连接字符串" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -TemplateDir ScaffoldTemplates

这个方案适合需要统一配置大量实体的场景,避免重复编写元数据类。

对比你当前用的视图模型方案:视图模型确实能实现UI层和数据层的分离,但如果只是为了保留属性元数据,分部类+元数据类型的方法更简洁,不需要维护重复的属性定义;Fluent API则完全避免了在实体类上添加注解,更符合EF Core的最佳实践;自定义模板适合大规模的统一配置需求。

内容的提问来源于stack exchange,提问作者Damol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 13:26:01