EF Core 5.0 - 更改“定义查询”映射实体时是不是需要生成迁移?

Posted

技术标签:

【中文标题】EF Core 5.0 - 更改“定义查询”映射实体时是不是需要生成迁移?【英文标题】:EF Core 5.0 - Do you need to generate a migration when changing a "Defining Query" -mapped entity?EF Core 5.0 - 更改“定义查询”映射实体时是否需要生成迁移? 【发布时间】:2021-06-01 07:52:24 【问题描述】:

我在我的 EF Core 5.0/MS SQL Server 数据模型中添加了一个实体类,它由定义查询(原始 SQL 查询,在我的数据库中没有与之对应的表或视图)支持。

当我对其进行更改(例如,添加一个新列)然后在包管理器控制台中运行Add-Migration 以创建迁移步骤时,它会生成一个带有空Up(MigrationBuilder migrationBuilder)Down(MigrationBuilder migrationBuilder) 方法的迁移。但是生成的 [MigrationName].Designer.cs 文件包含新列,并且我的 DbContext 的 ModelSnapshot 被修改为包含新列,因此 有些东西 发生了变化。

我的问题是,我是否需要在每次更改这些实体之一时添加迁移才能使我的应用正常运行?如果不需要它们,当我更新定义查询支持的实体时,什么被认为是更好的做法:

A.添加这些迁移,即使它们有空白的 Up(MigrationBuilder migrationBuilder)Down(MigrationBuilder migrationBuilder) 方法,因为模型已更改,或者

B.不生成迁移,只是在下次有人进行实际影响底层数据库结构的更改时获取这些更改?

代码 sn-ps(过度简化以删除识别数据):

实体类

public class Thing

    public int Id  get; set; 

    public string Name  get; set; 

实体配置:

public class ThingTypeConfiguration : IEntityTypeConfiguration<Thing>

    public void Configure(EntityTypeBuilder<Thing> builder)
    
        builder
            .HasNoKey()
            .ToView("Dummy") // This is here to work around an issue with the migrations auto-generating a table for the entity - see https://github.com/dotnet/efcore/issues/19972 
            .ToSqlQuery(
            @"SELECT
                [TableName].[IdColumn] AS Id,
                [TableName].[OtherColumn] AS Name
            FROM 
                [TableName]");
    

数据库上下文:

public class MyDbContext : DbContext

    public MyDbContext()
    
    

    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options)
    
    

    public virtual DbSet<Thing> Things  get; set; 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    
        if (!optionsBuilder.IsConfigured)
        
        
    

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        modelBuilder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);
    

生成的迁移部分类示例:

具有空 Up/Down 方法的部分类:

public partial class MyMigration : Migration

    protected override void Up(MigrationBuilder migrationBuilder)
    
    
    

    protected override void Down(MigrationBuilder migrationBuilder)
    

    

自动生成的 __.Designer.cs 文件(类的其余部分):

[DbContext(typeof(MyDbContext))]
[Migration("20210302175116_MyMigration")]
partial class MyMigration

    protected override void BuildTargetModel(ModelBuilder modelBuilder)
    
#pragma warning disable 612, 618
        modelBuilder
            .HasAnnotation("Relational:MaxIdentifierLength", 128)
            .HasAnnotation("ProductVersion", "5.0.3")
            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

        /* Entity configuration logic for all the other entities in my model.. */

        modelBuilder.Entity("MyDataProject.Thing", b =>
            
                b.Property<string>("Id")
                    .HasColumnType("int");

                b.Property<string>("Name")
                    .HasColumnType("nvarchar(max)");

                b.ToView("Dummy");

                b
                    .HasAnnotation("Relational:SqlQuery", "/* My SQL query */");
            );
#pragma warning restore 612, 618
    

【问题讨论】:

it generates a migration with empty Up(MigrationBuilder migrationBuilder) and Down(MigrationBuilder migrationBuilder) methods. -- 这些方法是否位于部分类中?我不是 EF Core 迁移方面的专家,但听起来它正在为您创建这些方法,以便您可以自定义迁移过程。 是的,它们在部分类中,类的其余部分由迁移过程自动生成(并具有所需的更改)。我也不是 EF Core 迁移方面的专家!我用部分类的示例更新了我的问题。 好的,这意味着您的新字段位于另一个部分类(生成的部分)中,您就完成了。您所指的空方法被放置到另一个部分类中,以便重新生成不会清除您放置在那里的任何代码。 【参考方案1】:

没有。如果数据库架构未更改,则无需添加新迁移。

哎呀,如果新架构与旧架构兼容,您甚至真的都不需要添加新迁移。例如,删除可选属性仍然是兼容的。

*.Designer 文件只是在生成 SQL 时偶尔提供有关模型的附加信息。而且,由于迁移不会生成 SQL,因此在这种情况下完全不用。

【讨论】:

以上是关于EF Core 5.0 - 更改“定义查询”映射实体时是不是需要生成迁移?的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 5.0 添加多对多使得一对多无法确定

为 ASP.NET Core 5.0 - EF Core 5.0 Web App 配置 PostgreSQL 连接字符串以在 MS 或 Linux 云上运行?

.NET Core 5.0 EF Migration 添加新的外部列

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

EF Core (< 5.0) HasComputedColumnSql - 在插入/更新或 SQL Server/AzureSQL 上的每个查询上计算?

实现 EF Core 6 自定义查询标记