簡體   English   中英

多對多關系中不完整的EF代碼優先級聯刪除

[英]Incomplete EF code-first cascade delete on many to many relationship

我有一個PhoneNumber實體,希望跨多個實體引用。 例如, 具有多個電話號碼的Contact實體和具有一個電話號碼的Business實體。

public class PhoneNumber
{
    [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Number { get; set; }
}

public class Contact
{
    [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }
}

public class Business
{
    [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [ForeignKey("PhoneNumber")]
    public int PhoneNumberId { get; set; }
    public virtual PhoneNumber PhoneNumber { get; set; }        
}

我已經設置了“ Contact和“ Business以便它們具有一種導航屬性。 另外,電話號碼是可選的。 我還為Contact設置了許多關系,以防止在添加遷移時EF添加Contact_Id列。 映射如下(注意,因為PhoneNumber沒有返回給Contact的nav屬性,所以使用WithMany() ):

modelBuilder.Entity<Contact>().HasMany(r => r.PhoneNumbers).WithMany()
            .Map(x => x.MapLeftKey("ContactId").MapRightKey("PhoneId"));

當我添加具有多個電話號碼的Contact ,它會很好地添加。 ContactPhoneNumbers表和ContactPhoneNumbers鏈接表的記錄。

但是,我遇到的問題是刪除聯系人時。 EF會正確刪除ContactPhoneNumbers鏈接表中的條目和Contact條目,但不會從PhoneNumbers表中刪除條目。 我已經看到了使用modelBuilder映射的示例,其中使用了WillCascadeOnDelete(true) ,但是在使用WithMany()時該選項不可用。

我需要怎么做才能使該級聯刪除正常工作? 此設置可能嗎? 還是我需要為每個實體(聯系和業務)使用單獨的PhoneNumbers表來建立一種關系,其中各個PhoneNumber表使用FK(例如Contact_Id )?

我是EF的新手,歡迎提出任何建議。 我可能會完全不對。

編輯:這是相關的遷移代碼...

CreateTable(
    "dbo.PhoneNumbers",
    c => new
        {
            Id = c.Int(nullable: false, identity: true),
            Number = c.String()
        })
    .PrimaryKey(t => t.Id);

CreateTable(
    "dbo.Contacts",
    c => new
        {
            Id = c.Int(nullable: false, identity: true)
        })
    .PrimaryKey(t => t.Id);

CreateTable(
    "dbo.ContactPhoneNumbers",
    c => new
        {
            ContactId = c.Int(nullable: false),
            PhoneId = c.Int(nullable: false),
        })
    .PrimaryKey(t => new { t.ContactId, t.PhoneId })
    .ForeignKey("dbo.Contacts", t => t.ContactId, cascadeDelete: true)
    .ForeignKey("dbo.PhoneNumbers", t => t.PhoneId, cascadeDelete: true)
    .Index(t => t.ContactId)
    .Index(t => t.PhoneId);

CreateTable(
    "dbo.Business",
    c => new
        {
            Id = c.Int(nullable: false),
            PhoneNumberId = c.Int(nullable: false)
        })
    .PrimaryKey(t => t.Id)
    .ForeignKey("dbo.PhoneNumbers", t => t.PhoneNumberId, cascadeDelete: true)
    .Index(t => t.Id)
    .Index(t => t.PhoneNumberId);

為了使級聯刪除工作,將要級聯的記錄必須具有外鍵才能回到要刪除的記錄。 因此,在您的示例中,您刪除了一個聯系人記錄。 因為它們是從ContactPhoneNumber到Contact的外鍵,所以級聯起作用。 由於從PhoneNumber到ContactPhoneNumber沒有外鍵,(外鍵則相反),級聯不會繼續。

這是因為您將關系定義為多對多。 如果您想嘗試根據需要在模型上執行級聯刪除,如果刪除了ContactPhoneNumber,然后刪除了其關聯的PhoneNumber,那么現在可能還有其他沒有有效PhoneNumber的ContactPhoneNumber(因為可以可以將多個ContactPhoneNumber更改為一個PhoneNumber)。 現在,這些將需要刪除,並且該過程將繼續。 數據庫不喜歡這種周期性級聯。

對我來說,尚不十分清楚為什么需要多對多關系,如果確實需要,則將無法對刪除執行級聯。 如果可以建立關系:

1 Contact-* ContactPhoneNumber 1- * PhoneNumber,然后您就可以配置級聯以使其按需工作。

暫無
暫無

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

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