簡體   English   中英

實體框架代碼首先使用額外的密鑰進行多對多

[英]Entity framework code first many to many with extra key

我正在嘗試創建一個鏈接表,該表將使我的產品表和附件表之間具有多對多關系。

我的課是這樣的:

public class Product {
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Accessory> Accessories { get; set; }
}

public class Accessory {
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Machine> Machine { get; set; }
}

public class Type {
    public int Id { get; set; }
    public string Name { get; set; }
}

如果配件類型不同,則同一配件可以在一個產品上出現多次,這將在鏈接表中確定。 像這樣:

public class ProductAccessoryLink {
    public int productId {get; set;}
    public int accessoryId {get; set;}
    public int typeId {get; set}
    public int sort {get; set;}
    public string notes {get; set}
}

這是正確的方法嗎?

編輯

這是我在運行更新數據庫時遇到的錯誤:

在表“ ProductAccessoryLinks”上引入FOREIGN KEY約束“ FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId”可能會導致循環或多個級聯路徑。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY約束。 無法創建約束。 請參閱先前的錯誤。

這是導致錯誤的sql:ALTER TABLE [dbo]。[ProductAccessoryLinks]添加約束[FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId] FOREIGN KEY([TypeId])參考[dbo]。[Types]([Id])刪除級聯

在您的情況下,您需要顯式映射聯結表。 您的模型將如下所示:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ProductAccessoryLink> ProductAccessoryLinks { get; set; }
}

public class Accessory
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ProductAccessoryLink> ProductAccessoryLinks { get; set; }
}

public class Type
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ProductAccessoryLink 
{
    public int ProductId { get; set; }
    public int AccessoryId { get; set; }
    public int TypeId { get; set; }
    public int sort { get; set; }
    public string notes { get; set; }

    public virtual Type Type { get; set; }
    public virtual Product Product { get; set; }
    public virtual Accessory Accessory { get; set; }
}

您可以通過OnModelCreating方式在上下文中配置覆蓋OnModelCreating方法的關系:

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<ProductAccessoryLink>().HasKey(i => new { i.ProductId, i.AccesoryId, i.TypeId});

    modelBuilder.Entity<ProductAccessoryLink>()
       .HasRequired(i => i.Product)
       .WithMany(k => k.ProductAccessoryLinks)
       .HasForeignKey(i=>i.ProductId);

    modelBuilder.Entity<ProductAccessoryLink>()
       .HasRequired(i => i.Accesory)
       .WithMany(k => k.ProductAccessoryLinks)
       .HasForeignKey(i=>i.AccesoryId);

    modelBuilder.Entity<ProductAccessoryLink>()
       .HasRequired(i => i.Type)
       .WithMany()
       .HasForeignKey(i=>i.TypeId);
}

EF使您可以直接配置嘗試的多對多關系。 因此,EF負責使用其要連接的表的適當鍵在數據庫中構建連接表。 (鍵既是聯接表的主鍵,又是指向聯接表的外鍵)。 這樣一來,您就可以在聯接表中獲取數據,而不必知道其存在。 但是,當您想對該表進行個性化設置(例如,添加一些其他屬性)時,需要像上面顯示的那樣顯式地映射它。

更新

當您具有級聯刪除的多個路徑而最終嘗試刪除Types表中的同一行時,會導致該異常。 要解決該問題,我建議您在這篇文章中檢查我的答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM