EntityFramework: CascadeOnDelete 只有当父对象被删除
EntityFramework: CascadeOnDelete only if parent object is deleted
我在使用 EntityFramework 和以下数据模型时遇到了一些麻烦(参见简化图)。
Matter 对象可以被认为是"main container"。有 Bill 和 BillRecord。从 Bill 到 BillRecord 之间存在一对多的关联。准确地说,一个Bill可以引用多个BillRecord(可能是0个),一个BillRecord最多可以引用一个bill
1) 我希望能够删除 BillRecord,但如果存在关联,则不应删除 Bill(这就是为什么我没有在 BillRecords 实体上为 Bill 设置 OnCascadeDelete)。同样,如果我删除一个 Bill,我不想删除可能关联的 BillRecord。
2) 但是,当我删除一个事项时,我希望所有内容都消失:事项、账单和账单记录。
使用以下代码,如果没有与 BillRecord 关联的 BillRecord,我设法做到 1) 正确和 2) 工作,如果有,我会收到以下错误。
System.Data.SqlServerCe.SqlCeException: The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = FK_dbo.BillRecordDboes_dbo.BillDboes_BillId ]
这是我的实体和 OnModelCreating 的逻辑
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MatterDbo>().HasMany<BillRecordDbo>(s => s.BillRecordDbos)
.WithRequired(s => s.Matter).HasForeignKey(s => s.MatterId).WillCascadeOnDelete(true);
modelBuilder.Entity<MatterDbo>().HasMany<BillDbo>(s => s.BillDbos)
.WithRequired(s => s.Matter).HasForeignKey(s => s.MatterId).WillCascadeOnDelete(true);
}
public class MatterDbo
{
public MatterDbo()
{
BillDbos = new List<BillDbo>();
BillRecordDbos = new List<BillRecordDbo>();
}
public Guid Id { get; set; }
public virtual List<BillDbo> BillDbos { get; set; }
public virtual List<BillRecordDbo> BillRecordDbos { get; set; }
}
public class BillRecordDbo
{
public Guid Id { get; set; }
public Guid MatterId { get; set; }
public virtual MatterDbo Matter { get; set; }
public Guid? BillId { get; set; }
public virtual BillDbo Bill { get; set; }
}
public class BillDbo
{
public BillDbo()
{
BilledRecords = new List<BillRecordDbo>();
}
public Guid Id { get; set; }
public virtual List<BillRecordDbo> BilledRecords { get; set; }
public Guid MatterId { get; set; }
public virtual MatterDbo Matter { get; set; }
}
当然,在删除事项时,我可以手动检查并删除 Bill 和 BillRecords 的所有关联,但我认为这是错误的 EF 用法。
我正在使用 EntityFramework 6.0 和 SQL CE 目标 .NET 4.0
非常感谢。
如果您确实需要 BillRecord 在其父项 Bill 实体被删除后保留在数据库中,则必须在删除父项之前将父项 属性 设置为 null。但是,在数据库中具有可为空的 FK 通常表明可能有更好的数据库设计解决方案。
我在使用 EntityFramework 和以下数据模型时遇到了一些麻烦(参见简化图)。
Matter 对象可以被认为是"main container"。有 Bill 和 BillRecord。从 Bill 到 BillRecord 之间存在一对多的关联。准确地说,一个Bill可以引用多个BillRecord(可能是0个),一个BillRecord最多可以引用一个bill
1) 我希望能够删除 BillRecord,但如果存在关联,则不应删除 Bill(这就是为什么我没有在 BillRecords 实体上为 Bill 设置 OnCascadeDelete)。同样,如果我删除一个 Bill,我不想删除可能关联的 BillRecord。
2) 但是,当我删除一个事项时,我希望所有内容都消失:事项、账单和账单记录。
使用以下代码,如果没有与 BillRecord 关联的 BillRecord,我设法做到 1) 正确和 2) 工作,如果有,我会收到以下错误。
System.Data.SqlServerCe.SqlCeException: The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = FK_dbo.BillRecordDboes_dbo.BillDboes_BillId ]
这是我的实体和 OnModelCreating 的逻辑
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MatterDbo>().HasMany<BillRecordDbo>(s => s.BillRecordDbos)
.WithRequired(s => s.Matter).HasForeignKey(s => s.MatterId).WillCascadeOnDelete(true);
modelBuilder.Entity<MatterDbo>().HasMany<BillDbo>(s => s.BillDbos)
.WithRequired(s => s.Matter).HasForeignKey(s => s.MatterId).WillCascadeOnDelete(true);
}
public class MatterDbo
{
public MatterDbo()
{
BillDbos = new List<BillDbo>();
BillRecordDbos = new List<BillRecordDbo>();
}
public Guid Id { get; set; }
public virtual List<BillDbo> BillDbos { get; set; }
public virtual List<BillRecordDbo> BillRecordDbos { get; set; }
}
public class BillRecordDbo
{
public Guid Id { get; set; }
public Guid MatterId { get; set; }
public virtual MatterDbo Matter { get; set; }
public Guid? BillId { get; set; }
public virtual BillDbo Bill { get; set; }
}
public class BillDbo
{
public BillDbo()
{
BilledRecords = new List<BillRecordDbo>();
}
public Guid Id { get; set; }
public virtual List<BillRecordDbo> BilledRecords { get; set; }
public Guid MatterId { get; set; }
public virtual MatterDbo Matter { get; set; }
}
当然,在删除事项时,我可以手动检查并删除 Bill 和 BillRecords 的所有关联,但我认为这是错误的 EF 用法。
我正在使用 EntityFramework 6.0 和 SQL CE 目标 .NET 4.0
非常感谢。
如果您确实需要 BillRecord 在其父项 Bill 实体被删除后保留在数据库中,则必须在删除父项之前将父项 属性 设置为 null。但是,在数据库中具有可为空的 FK 通常表明可能有更好的数据库设计解决方案。