我先在winforms应用程序上使用EF 6.4.0代码,但Cascade删除不起作用
下面是我的课程
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是可为null的整数。
所以我期望EF删除国家/地区记录并将PM_COUNTRY设置为null
我做错什么了吗?
我不确定为什么约定不起作用,但是您可以像这样配置它(在重命名实体之后:
modelBuilder.Entity<Player>()
.HasOptional(c => c.Country)
.WithMany()
.HasForeignKey(p => p.CountryID)
.WillCascadeOnDelete(true);
OP想要DELETE一条COUNTRIES
记录,并期望所有具有相应PLAYERS_M
值的PM_COUNTRY
将被设置为null。
为了实现这一点,PLAYERS_M.PM_COUNTRY
被正确定义为可为空的字段(int?
),但是您仍然需要在模型中将该关系声明为可选关系以强制执行此行为。
根据文档,OneToManyCascadeDeleteConvention在这里没有帮助:启用所有required关系的级联删除的约定。
要解决此问题,您可以在OnModelCreating
方法中添加以下Fluent符号:
modelBuilder.Entity<PLAYERS_M>()
.HasOptional(p => p.COUNTRIES)
.WithMany()
.HasForeignKey(p => p.PM_COUNTRY)
.WillCascadeOnDelete(true); // this is where the magic is!
此行为极有可能是设计使然,使用这样的Cascade Delete来消除可选引用可以非常快速地创建孤立的记录,通过使用流利的符号,您不得不为每个关系分别做出业务决策。 请谨慎使用此功能。