Entity framework migrations 当密钥位于基类中时,EF迁移DropForeignKey失败

Entity framework migrations 当密钥位于基类中时,EF迁移DropForeignKey失败,entity-framework-migrations,entity-framework-5,Entity Framework Migrations,Entity Framework 5,我正在尝试更新EF 5.0.0-rc代码一级库的数据模型。Up()方法中的第一个命令是 DropForeignKey("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" }, "dbo.ChileProducts"); 但我得到了一个SqlException:“FK_dbo.ChileInventory_dbo.ChileProducts\u LotInventoryItemTypeId\u Chil

我正在尝试更新EF 5.0.0-rc代码一级库的数据模型。Up()方法中的第一个命令是

DropForeignKey("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" }, "dbo.ChileProducts");
但我得到了一个SqlException:“FK_dbo.ChileInventory_dbo.ChileProducts\u LotInventoryItemTypeId\u ChileProductId”不是约束。无法删除约束

我认为错误的原因是我的ChileProducts类从它的基类获取了它的关键属性。由于DropForeignkey方法没有重载,它接受主列名,因此我相信EF无法确定要删除的正确约束。我还应该指出,异常消息中显示的约束名称与数据库中的约束名称不匹配(因此出现错误…)

下面是数据模型和迁移方法。但首先要简要说明迁移背后变化的性质:InventoryBase类的每个派生都通过InventoryTypeId和[InventoryTypeSpecific]ProductId的复合键定义产品类型。例如,ChileInventory将其特定的chile类型标识为InventoryItemTypeId=[ChileInventoryTypeId]和ChileProductId=[ChileProductId]。PackagingInventory将其包装类型标识为InventoryItemTypeId=[PackagingInventoryTypeId]和PackagingProductId=[PackagingProductId]。等等

我正在进行的模型更改是将[InventoryTypeSpecific]ProductId从每个InventoryBase衍生产品提升到基础中。这将导致所有InventoryBase派生对象共享一个公共ProductId属性,该属性与InventoryItemTypeId一起,将启用从InventoryBase到ProductBase的导航;这在以前的模型中是不可能的

提前感谢您的建议和考虑。 --文尼

数据模型 智利产品 智利库存
以下是我发现的一项工作:


使用DropForeignKey重载,该重载包含参数principalName和name——在本例中,这意味着约束名称!它有点脆弱,因为它需要预先知道约束名称,但它可以按预期工作。

如果您的初始模型是使用EF 4.3创建的,那么您在EF 5.0中会出现此类错误,因为生成PK/FK约束名称的规则在EF的这两个版本之间发生了更改


有关详细信息和其他可能的解决方案,请参阅此部分。

是否有FK命名更改的官方信息?在4.3或更高版本中创建的迁移从db模式中删除FK,而在4.3之前的版本中创建FK,当您应用迁移时,这是一个突破性的更改!这是一个多功能的解决方案
public abstract class ProductBase
{
    [Key]
    [Column(Order = 0)]
    public virtual int InventoryItemTypeId { get; set; }

    [Key]
    [Column(Order = 1)]
    public virtual int Id { get; set; }

    [StringLength(150)]
    public virtual string Name { get; set; }

    [ForeignKey("InventoryItemTypeId")]
    public virtual InventoryItemType InventoryItemType { get; set; }

    public virtual bool IsActive { get; set; }
}
public class ChileProduct : ProductBase
{
    public virtual int ChileTypeId { get; set; }

    [ForeignKey("ChileTypeId")]
    public virtual ChileType ChileType { get; set; }
}
public abstract class InventoryBase
{
    [Key]
    [Column(Order = 0, TypeName = "Date")]
    public virtual DateTime DateCreated { get; set; }

    [Key]
    [Column(Order = 1)]
    public virtual int Sequence { get; set; }

    [Key]
    [Column(Order = 2)]
    public virtual int LotInventoryItemTypeId { get; set; }

    [Column(TypeName = "Date")]
    public virtual DateTime LotDateCreated { get; set; }

    public virtual int LotSequence { get; set; }

    public virtual int ProductId { get; set; }

    [ForeignKey("LotInventoryItemTypeId, LotDateCreated, LotSequence")]
    public virtual Lot Lot { get; set; }

    [ForeignKey("LotInventoryItemTypeId")]
    public virtual InventoryItemType ItemType { get; set; }

    public virtual ICollection<InventoryQuantityByLocation> QuantitiesByLocation { get; set; }

    [ForeignKey("LotInventoryItemTypeId, ProductId")]
    public virtual ProductBase ProductBase { get; set; }
}

public class ChileInventory : InventoryBase
{
    [Column(TypeName = "Date")]
    public virtual DateTime? ProductionBatchDateCreated { get; set; }

    public virtual int? ProductionBatchSequence { get; set; }

    public virtual int PackagingInventoryItemTypeId { get; set; }

    public virtual int PackagingProductId { get; set; }

    [ForeignKey("ProductionBatchDateCreated, ProductionBatchSequence")]
    public virtual ProductionBatch ProductionBatch { get; set; }

    [ForeignKey("LotInventoryItemTypeId, ProductId")]
    public virtual ChileProduct ChileProduct { get; set; }

    [ForeignKey("PackagingInventoryItemTypeId, PackagingProductId")]
    public virtual PackagingProduct PackagingProduct { get; set; }

}
public override void Up()
    {
        DropForeignKey("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" }, "dbo.ChileProducts");
        DropForeignKey("dbo.PackagingInventory", new[] { "LotInventoryItemTypeId", "PackageId" }, "dbo.PackagingProducts");
        DropForeignKey("dbo.AdditiveInventory", new[] { "LotInventoryItemTypeId", "AdditiveProductId" }, "dbo.AdditiveProducts");
        DropIndex("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" });
        DropIndex("dbo.PackagingInventory", new[] { "LotInventoryItemTypeId", "PackageId" });
        DropIndex("dbo.AdditiveInventory", new[] { "LotInventoryItemTypeId", "AdditiveProductId" });
        AddColumn("dbo.Inventory", "ProductId", c => c.Int(nullable: false));
        AddForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts", new[] { "InventoryItemTypeId", "Id" });
        AddForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts", new[] { "InventoryItemTypeId", "Id" });
        AddForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts", new[] { "InventoryItemTypeId", "Id" });
        AddForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts", new[] { "InventoryItemTypeId", "Id" });
        CreateIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        CreateIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        CreateIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        CreateIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        DropColumn("dbo.ChileInventory", "ChileProductId");
        DropColumn("dbo.PackagingInventory", "PackageId");
        DropColumn("dbo.AdditiveInventory", "AdditiveProductId");
    }

    public override void Down()
    {
        AddColumn("dbo.AdditiveInventory", "AdditiveProductId", c => c.Int(nullable: false));
        AddColumn("dbo.PackagingInventory", "PackageId", c => c.Int(nullable: false));
        AddColumn("dbo.ChileInventory", "ChileProductId", c => c.Int(nullable: false));
        DropIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        DropIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        DropIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        DropIndex("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" });
        DropForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts");
        DropForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts");
        DropForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts");
        DropForeignKey("dbo.Inventory", new[] { "LotInventoryItemTypeId", "ProductId" }, "dbo.AdditiveProducts");
        DropColumn("dbo.Inventory", "ProductId");
        CreateIndex("dbo.AdditiveInventory", new[] { "LotInventoryItemTypeId", "AdditiveProductId" });
        CreateIndex("dbo.PackagingInventory", new[] { "LotInventoryItemTypeId", "PackageId" });
        CreateIndex("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" });
        AddForeignKey("dbo.AdditiveInventory", new[] { "LotInventoryItemTypeId", "AdditiveProductId" }, "dbo.AdditiveProducts", new[] { "InventoryItemTypeId", "Id" });
        AddForeignKey("dbo.PackagingInventory", new[] { "LotInventoryItemTypeId", "PackageId" }, "dbo.PackagingProducts", new[] { "InventoryItemTypeId", "Id" });
        AddForeignKey("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" }, "dbo.ChileProducts", new[] { "InventoryItemTypeId", "Id" });
    }