6

EF 5.0.0-rc code-first クラス ライブラリのデータ モデルを更新しようとしています。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 へのナビゲーションが可能になります。これは前のモデルでは不可能です。

アドバイスとご検討ありがとうございます。--ヴィニー

データ モデル

チリ産

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

2 に答える 2

12

私が見つけた回避策の1つは次のとおりです。

パラメータprincipalNamenameを含む DropForeignKey オーバーロードを使用します。この場合は、制約名を意味します! 事前に制約名の知識が必要なため、もう少し壊れやすいですが、期待どおりに機能します。

于 2012-07-18T04:28:29.897 に答える
5

最初のモデルが EF 4.3 で作成された場合、EF の 2 つのバージョン間で PK/FK 制約名を生成するためのルールが変更されているため、EF 5.0 でこのようなエラーが発生します。

詳細と別の可能な解決策については、この質問を参照してください。

于 2012-09-14T16:03:44.277 に答える