繁体   English   中英

实体框架代码优先迁移不生成外键并忽略 ForeignKey 数据注释

[英]Entity Framework code-first migrations does not generate a foreign key and ignores the ForeignKey data annotation

我正在尝试使用 EF 代码优先迁移将外键添加到我的数据库表中,但是当我运行add-migration时,生成的迁移中的Up()Down()方法为空。

外键应链接到的基表是Reservation ,我尝试添加键的表是Batch

预订model class:

public class Reservation
{
    [Key]
    public int ReservationId { get; set; }

    public virtual ICollection<Batch> Batches { get; set; }
    
    ...
}

批次model class:

public class Batch
{
   [Key]
   public int BatchId { get; set; }
   
   public int ReservationId { get; set; }

   [ForeignKey("ReservationId")]
   public Reservation Reservation { get; set; }

   ...
}

Reservation属性以前称为TempReservation并且没有[ForeignKey]注释,这就是为什么首先没有创建外键的原因。

我尝试通过添加[ForeignKey]注释并将属性名称更改为Reservation来修复它,如上面的代码片段所示,但无济于事。

迁移总是忽略我的更改,给我空的Up()Down()

我还有其他遵循相同“结构”的 model 类,它们都有外键,没有任何问题。 唯一的区别是我在创建Batch表之后添加了这个 FK。

如果您从头开始,您的代码 model 设置应该可以工作,因此您的 model 看起来没问题。 问题是,由于第一次不使用[ForeignKey]属性,您的数据库模式现在可能有一个名为Reservation_ReservationId的附加Shadow Property列。 但是,由于此字段不是 model 中的活动声明,因此很难直接定位,因为您的约定配置会极大地影响这一点,例如,如果您配置了适当的约定,影子属性可能已经命名为ReservationId

尝试通过添加 [ForeignKey] 注释并将属性名称更改为 Reservation 来修复它,如上面的代码片段所示,但无济于事。

如上所述,数据库可能已经在数据库中生成了正确的外键,基于public virtual ICollection<Batch> Batches { get; set; } public virtual ICollection<Batch> Batches { get; set; } public virtual ICollection<Batch> Batches { get; set; }

需要记住的一点:

  • 每当对 model 进行更改以重命名字段和/或修改现有字段的索引或关系时,您必须在单独的迁移中执行这些操作,否则迁移生成逻辑无法理解您将不得不手动应用更改。

    • 如果您一次性完成这些操作,您几乎总是必须以某种方式手动编辑迁移文件。
  • 在将您手动修改的迁移逻辑应用到数据库之后,如果您现在运行add-migration命令,它应该会生成一个空迁移。 如果是这种情况,那么您通常可以继续前进。

相反,您可以遵循以下过程:

  1. 重命名导航属性和任何其他字段。
  2. Add-Migration ... 查看生成的 output
  3. '更新数据库`...
  4. 添加ForeignKey属性
  5. Add-Migration ... 查看 output,如果为空,请检查外键是否尚未在数据库中正确定义
  6. '更新数据库'...如有必要

Code First 迁移并非完美的开箱即用

它仍然是一个非常有用的工具,但您需要查看生成的代码并根据需要添加。 扩展它以支持默认值声明或任何 SQL DDL 管理查询在您需要时或在您需要时并不难。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM