在此处研究级联删除和浏览问题后,我认为以下方案可以正常工作
实体有很多:
public partial class master
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public master()
{
analysis = new HashSet<analysis>();
}
[Key]
public int id { get; set; }
[StringLength(50)]
public string description { get; set; }
public virtual ICollection<analysis> analysis { get; set; }
}
实体有一个:
public partial class analysis
{
[Key]
public int id { get; set; }
[StringLength(50)]
public string description { get; set; }
public int? master_id { get; set; }
public virtual master master { get; set; }
}
analysis
实体上的外键可以为空,因此当尝试删除master
记录时,级联删除会自动将FK设置为null。
该配置位于我的Context
:
public class Context : DbContext
{
public Context() : base("Context")
{
this.Configuration.LazyLoadingEnabled = true;
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<Context>());
}
public virtual DbSet<master> master { get; set; }
public virtual DbSet<analysis> analysis { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<master>()
.HasMany(e => e.analysis)
.WithOptional(e => e.master)
.HasForeignKey(e => e.master_id)
.WillCascadeOnDelete(true);
}
}
然后,当我尝试通过将id传递到以下内容时删除master
记录(通用repo片段,在删除没有分析的master
记录时,这样可以正常工作):
public void Delete(int id)
{
var entity = FindByKey(id);
_dbSet.Remove(entity);
_context.SaveChanges();
}
我收到错误
无法删除或更新父行:外键约束失败
在此记录上。我在这里错过了什么?
答案 0 :(得分:1)
使用CascaseOnDelete应该镜像数据库上的级联规则。使用CodeFirst将关系设置为Required时,EF会将映射和架构中的这两者映射为删除级联。对于可选关系,情况并非如此,它假设删除父级将使子级孤立,因为子级由于其无法使用FK而接受没有父级的存在。但是,如果不了解子记录,它就无法清除FK中的ID或删除数据,因此它依赖于DB设置的任何内容。
您仍然可以使用.WillCascadeOnDelete(),但要使其工作,上下文需要了解子项。例如,在新的背景下:
var master = _db.Masters.Find(id);
_db.Masters.Remove(master);
这通常会因FK约束错误而失败。 (SQL Server)错误消息与您的不同,所以我怀疑Tetsuya是不同的提供者?
要解决此问题,您可以使用:
var master = _db.Masters.Include(x=>x.analysis).Find(id);
_db.Masters.Remove(master);
虽然对于包含所有孩子的较大图表的对象来说这可能很乏味。
作为一般规则,如果要使用级联删除,则需要确保数据库架构设置为具有级联删除行为。使用无效FK和级联删除规则,原始代码应按预期运行。或者,将级联规则设置为“Set to Null”将使子记录孤立为空FK。 (EF没有错误)