我正在尝试更新EF 5.0.0-rc代码优先类库的数据模型。 Up()方法中的第一个命令是
DropForeignKey("dbo.ChileInventory", new[] { "LotInventoryItemTypeId", "ChileProductId" }, "dbo.ChileProducts");
但是我收到了SqlException:'FK_dbo.ChileInventory_dbo.ChileProducts_LotInventoryItemTypeId_ChileProductId'不是约束。无法放弃约束。
我认为错误的原因是因为我的ChileProducts类从它的基类得到了它的关键属性。由于DropForeignkey方法没有接受主列名称的重载,我相信EF无法确定要删除的正确约束。我还应该指出,异常消息中显示的约束名称与数据库中的约束名称不匹配(因此错误...)
您将在下面找到数据模型和迁移方法。但首先要快速了解迁移背后的变化性质:InventoryBase类的每个衍生产品都通过InventoryTypeId和[InventoryTypeSpecific] ProductId的组合键定义产品类型。例如,ChileInventory会将其特定的智能类型类型识别为InventoryItemTypeId = [ChileInventoryTypeId]和ChileProductId = [ChileProductId]。 PackagingInventory会将其包装类型标识为InventoryItemTypeId = [PackagingInventoryTypeId]和PackagingProductId = [PackagingProductId]。等等。
我正在努力推出的模型更改是将[InventoryTypeSpecific] ProductId从每个InventoryBase衍生产品升级到基础。这将导致所有InventoryBase派生对象共享一个公共ProductId属性,该属性与InventoryItemTypeId一起将启用从InventoryBase到ProductBase的导航;这在以前的模型中是不可能的。
先谢谢你的建议和考虑。 --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; }
}
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" });
}
答案 0 :(得分:12)
这是我发现的一项工作:
使用包含参数 principalName 和 name 的DropForeignKey重载 - 在本例中为约束名称!它有点脆弱,因为它需要事先知道约束名称,但它按预期工作。
答案 1 :(得分:4)
如果您的初始模型是使用EF 4.3创建的,那么您将在EF 5.0中出现此类错误,因为生成PK / FK约束名称的规则在EF的这两个版本之间发生了变化。
有关详细信息和其他可能的解决方案,请参阅此question。