当密钥在基类中时,EF迁移DropForeignKey失败 [英] EF Migrations DropForeignKey fails when key is in a base class

查看:51
本文介绍了当密钥在基类中时,EF迁移DropForeignKey失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to update my data models for an EF 5.0.0-rc code-first class library. The first command in the Up() method is

DropForeignKey("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" }, "dbo.ChileProducts");

但我遇到了SqlException: FK_dbo.ChileInventory_dbo.ChileProducts_LotInventoryItemTypeId_ChileProductId不是约束。无法放弃约束。

but I'm getting a SqlException: 'FK_dbo.ChileInventory_dbo.ChileProducts_LotInventoryItemTypeId_ChileProductId' is not a constraint. Could not drop constraint.

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

I think that the cause for the error is due to the fact that my ChileProducts class get's it's key properties from its base class. Since there is no overload of the DropForeignkey method which accepts the principal column name(s), I believe EF is unable to determine the correct constraint to drop. I should also point out that the constraint name displayed in the exception message does not match up with the constraint name in the database (hence the error...)

在您下方会找到数据模型和迁移方法。但是,首先要简要介绍一下迁移背后的更改的性质:InventoryBase类的每个派生类都通过InventoryTypeId和[InventoryTypeSpecific] ProductId的复合键定义了产品类型。例如,ChileInventory将其特定的智利类型类型标识为InventoryItemTypeId = [ChileInventoryTypeId]和ChileProductId = [ChileProductId]。 PackagingInventory将其包装类型标识为InventoryItemTypeId = [PackagingInventoryTypeId]和PackagingProductId = [PackagingProductId]。等等。

Below you'll find the data models and the migration methods. But first a quick note about the nature of the change behind the migration: Each derivative of the InventoryBase class defines product type through the composite key of InventoryTypeId and [InventoryTypeSpecific]ProductId. For example, ChileInventory would identify it's particular chile type type as InventoryItemTypeId = [ChileInventoryTypeId] and ChileProductId = [ChileProductId]. PackagingInventory would identify it's packaging type as InventoryItemTypeId = [PackagingInventoryTypeId] and PackagingProductId = [PackagingProductId]. And so on.

我正在尝试进行的模型更改是[InventoryTypeSpecific] ProductId从每个InventoryBase派生对象到基准的高度。这将导致所有从InventoryBase派生的对象共享一个公共的ProductId属性,该属性与InventoryItemTypeId一起可以启用从InventoryBase到ProductBase的导航;

The model change I'm working to roll out is the elevation of the [InventoryTypeSpecific]ProductId from each InventoryBase derivative into the base. This would result in all InventoryBase derived objects sharing a common ProductId property which, in conjunction with the InventoryItemTypeId, would enable navigation from InventoryBase to ProductBase; which isn't possible in the previous model.

在此先感谢您的建议和考虑。
--Vinney

Thanks, in advance for your advice and consideration. --Vinney

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; }
}



智利库存



Chile Inventory

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; }

}



迁移



Migration

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" });
    }


推荐答案

如果创建了初始模型在EF 4.3中,由于在这两个版本的EF之间生成PK / FK约束名称的规则已更改,因此在EF 5.0中将出现此类错误。

If your initial model was created with the EF 4.3 then you will have such errors in EF 5.0 since the rules for generating PK/FK constraint names have changed between these two versions of the EF.

问题以获取详细信息和另一种可能的解决方案。

See this question for details and another possible solution.

这篇关于当密钥在基类中时,EF迁移DropForeignKey失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆