[英]How do I configure Entity Framework cascade delete to work properly with a one to many relationship?
在研究了级联删除并在此处浏览问题之后,我认为以下情况将起作用
有很多实体:
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
记录时(通用存储库代码段,当删除不带分析的master
记录时,此方法可以正常工作):
public void Delete(int id)
{
var entity = FindByKey(id);
_dbSet.Remove(entity);
_context.SaveChanges();
}
我得到一个错误
无法删除或更新父行:外键约束失败
在这个记录上。 我在这里想念什么?
使用CascaseOnDelete应该在数据库上镜像级联规则。 使用CodeFirst将关系设置为“必需”时,EF会在映射和架构中将其映射为删除级联。 在使用可选关系的情况下,情况并非如此,它假定删除父级将使子级变为孤儿,因为子级由于其可空值而接受没有父级的存在。 但是,在不了解子记录的情况下,它无法从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和级联删除规则,原始代码应按预期运行。 或者,将级联规则设置为“设置为空”将使子记录变为空FK。 (EF没有错误)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.