[英]Entity Framework Core Code-First: Cascade delete on a many-to-many relationship
[英]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
,它會很好地添加。 有Contact
, PhoneNumbers
表和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.