[英]How to properly enable EF cascade delete with conventions
我在 winforms 應用程序上使用 EF 6.4.0 codefirst 並且級聯刪除不起作用
下面是我的課程
public class PLAYERS_M
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PM_ROWID { get; set; }
public string PM_PLAYER_ID { get; set; }
public string PM_FULLNAME { get; set; }
public int? PM_COUNTRY { get; set; }
public bool PM_IS_HOH { get; set; }
public string PM_QUOTE { get; set; }
public byte[] PM_PHOTO { get; set; }
[ForeignKey("PM_COUNTRY")]
public virtual COUNTRIES COUNTRIES { get; set; }
}
public class COUNTRIES
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CO_ROWID { get; set; }
public string CO_CODE { get; set; }
public string CO_NAME { get; set; }
}
我添加了以下方法來在 dbcontext 上啟用級聯刪除
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Add<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Add<ManyToManyCascadeDeleteConvention>();
base.OnModelCreating(modelBuilder);
}
但是我收到以下錯誤
“DELETE 語句與 REFERENCE 約束“FK_dbo.PLAYERS_M_dbo.COUNTRIES_PM_COUNTRY”沖突。沖突發生在數據庫“MpContext”、表“dbo.PLAYERS_M”、列“PM_COUNTRY”中。”
如果您觀察到外鍵 PM_COUNTRY 是可為空的 int。
所以我期待 EF 刪除國家記錄並將 PM_COUNTRY 設置為空
難道我做錯了什么?
我不確定為什么約定不起作用,但您可以像這樣配置它(重命名實體后):
modelBuilder.Entity<Player>()
.HasOptional(c => c.Country)
.WithMany()
.HasForeignKey(p => p.CountryID)
.WillCascadeOnDelete(true);
OP想刪除一個COUNTRIES
記錄,並期望所有PLAYERS_M
有相應的PM_COUNTRY
值將被設置為null。
為了實現這一點, PLAYERS_M.PM_COUNTRY
被正確定義為可空字段( int?
),但您仍然需要在模型中將關系聲明為可選以強制執行此行為。
根據文檔, OneToManyCascadeDeleteConvention在這里沒有幫助:Convention to enable cascade delete for any required關系。
為了解決這個問題,您可以將以下Fluent Notation添加到您的OnModelCreating
方法中:
modelBuilder.Entity<PLAYERS_M>()
.HasOptional(p => p.COUNTRIES)
.WithMany()
.HasForeignKey(p => p.PM_COUNTRY)
.WillCascadeOnDelete(true); // this is where the magic is!
這種行為很可能是設計使然,使用像這樣的級聯刪除來消除可選引用可以非常快速地創建孤立記錄,通過使用流暢的表示法,您被迫單獨為每個關系做出業務決策。 請謹慎使用此功能。
我通過將以下屬性添加到 COUNTRIES 類解決了我的問題
[ForeignKey("PM_COUNTRY")]
public virtual List<PLAYERS_M> PLAYERS_M { get; set; }
public class COUNTRIES
{
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CO_ROWID { get; set; }
public string CO_CODE { get; set; }
public string CO_NAME { get; set; }
[ForeignKey("PM_COUNTRY")]
public virtual List<PLAYERS_M> PLAYERS_M { get; set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.