简体   繁体   English

了解.net mvc(实体框架)中特定关系的级联删除?

[英]Understanding cascade delete in a specific relationship in .net mvc (entity framework)?

If I have a relationship like this in a .NET MVC project using entity framework (dbsets in a database context with models etc.). 如果我在使用实体框架(具有模型等的数据库上下文中的dbset)的.NET MVC项目中具有这样的关系。

class A {
  contains a list of class C objects (one-to-many)
}

class B {
 contains a list of class C objects (one-to-many), often many of the
 same class C entries which class A uses aswell
}

class C {
  contains class D elements
}

class D { }

So the main problem is that class A is a model I want to delete often as the data in it is only supposed to exist for a fixed amount of time (then it is deleted by a cron job), but for some reason when I remove class A entries it seems to mess with the relation between class C and class D, removing class D items from my class C entries in the database. 所以主要的问题是,类A是我想经常删除的模型,因为它中的数据只应存在固定的时间(然后由cron作业删除),但是由于某种原因,当我删除它时A类条目似乎弄乱了C类和D类之间的关系,从而从数据库中的C类条目中删除了D类项目。

Is there some way I can delete entries in my class A database table, while making sure that it leaves ALL the other tables alone completely and without exception? 有什么方法可以删除我的类A数据库表中的条目,同时确保它完全无一例外地将所有其他表都保留下来?

I've read on disabling cascade delete, but to be honest I'm confused on how I'm supposed to understand what weird relation that's into play in this particular context and I'm not quite sure what I should be disabling it on. 我已经阅读了禁用级联删除的内容,但是老实说,我对如何理解这种特殊情况下发生的奇怪关系感到困惑,并且我不确定应该禁用什么。

I hope this example makes sense I've tried to explain it as simply as possible. 我希望这个例子有意义,我已经尝试过尽可能简单地解释它。

By default EF has a OneToManyCascadeDeleteConvention enabled. 默认情况下,EF启用了OneToManyCascadeDeleteConvention This works like by setting a SQL cascade delete on the foreign key between the tables. 就像通过在表之间的外键上设置SQL级联删除操作一样。 When the primary object is deleted, any objects that are foreign keyed to that object will also be deleted. 当删除主要对象时,任何外键指向该对象的对象也将被删除。 Thus, in your example, when you delete A it will also delete all C objects that are in the collection. 因此,在您的示例中,当删除A它还将删除集合中的所有C对象。 And because we cascade it will also delete all of the D objects (assuming you mean that C contained a one-to-many collection of D objects) that are in all those C object's collections. 并且由于我们级联,它还将删除所有C对象集合中的所有D对象(假设您的意思是C包含一对多的D对象集合)。

The OneToManyCascadeDeleteConvention , however, only applies if the foreign key field is set to being required. 但是,仅在将外键字段设置为必需时,才应用OneToManyCascadeDeleteConvention Setting it to nullable (as in the example below) should disable the convention. 将其设置为可为空(如下面的示例所示)应禁用约定。

public class ObjectA 
{
     public int ObjectAId { get; set; }
     public virtual ICollection<ObjectC> ObjectCCollection { get; set; }
}

public class ObjectC 
{
     public int? ObjectAId { get; set; } 
     public virtual ObjectA ObjectA { get; set; }
}

That being said, you can also selectively remove the cascade between ObjectA to ObjectC during entity configuration using an EntityTypeConfiguration . 话虽如此,您还可以在使用实体类型配置EntityTypeConfiguration配置期间有选择地删除ObjectAObjectC之间的级联。

internal class ObjectCMap : EntityTypeConfiguration<ObjectC>
{
    public ObjectCMap()
    {
        this.HasOptional(o => o.ObjectA).WithMany(o => o.ObjectCCollection).WillCascadeOnDelete(false);
    }
}

and then register it with the model builder in the DbContext 然后在DbContext向模型构建器注册

modelBuilder.Configurations.Add(new ObjectCMap());

If the foreign key field on ObjectC isn't nullable, however, SQL will throw a foreign key error when you try to delete ObjectA . 但是,如果ObjectC上的外键字段不可为空,则当您尝试删除ObjectA时,SQL将引发外键错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM