简体   繁体   English

尝试级联删除时出错

[英]Error while trying to cascade-delete

I'm getting the following error message while trying to delete an item from the db: 尝试从数据库中删除项目时,出现以下错误消息:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. 操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。 When a change is made to a relationship, the related foreign-key property is set to a null value. 对关系进行更改时,相关的外键属性将设置为空值。 If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted. 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

I've read many topics about this issue, but none of them seem to help (or maybe i didn't understand them very well). 我已经阅读了许多有关此问题的主题,但是似乎没有一个对您有帮助的(或者也许我不太了解它们)。

my models are: 我的模型是:

public class ARDOperation
    {    
        [Key]                
        public int ARD { get; set; }

        [Required]               
        public virtual ICollection<Act> Actions { get; set; }

        public ARDOperation()
        {
            this.Actions = new List<Act>();
        }

    }
public class Act
{                      
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ARDID { get; set; }
    public int ARDOperationId { get; set; }

    [ForeignKey("ARDOperationId")]        
    public virtual ARDOperation ARDOperation { get; set; }

    public string Data { get; set; }

    [EnumDataType(typeof(ARDState))]
    public ARDState State { get; set; }
}

I Also defined a fluent API: 我还定义了一个流畅的API:

    public class ARDOperationDBContext : DbContext
    {            
        public DbSet<ARDOperation> ARDOperation { get; set; }
        //public DbSet<Act> Act { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Act>()
            .HasRequired(t => t.ARDOperation)
            .WithMany(t => t.Actions)
            .HasForeignKey(d => d.ARDOperationId)
            .WillCascadeOnDelete(true);                

            //modelBuilder.Entity<ARDOperation>()

        }

The method in controller: 控制器中的方法:

        internal void RemoveAction(int ARDID)
        {
        var op = ARDOperationDB.ARDOperation.Find(ARDID);
        if (op != null)
        {
            //will not remove the "idle" action
            if (op.Actions.Count > 1)                                
            {
                Act act = op.Actions.ElementAt(1);                                        
                op.Actions.Remove(act);                    
                //ARDOperationDB.Entry(op).State = EntityState.Modified;
                ARDOperationDB.SaveChanges();                                                           
            }                
        }
    }

I've tried to define the "ARDOperationId" property as nullable (int?) using code-first approach and i'm not getting any errors this way, but the child's data still remain in the DB. 我尝试使用代码优先方法将“ ARDOperationId”属性定义为可为空(int?),并且我没有通过这种方式得到任何错误,但是子级的数据仍然保留在DB中。

I think that i'm missing something related to the access to the Act model. 我认为我缺少与访问该法案模型有关的内容。

Will appreciate any help, Yuval. 谢谢您的帮助,尤瓦尔。

Take a look at [this answer][1] from an EF guru about the remove method. 看看EF专家关于remove方法的[this answer] [1]。

EntityCollection.Remove(childEntity) marks the relationship between parent and childEntity as Deleted. EntityCollection.Remove(childEntity)将parent和childEntity之间的关系标记为Deleted。 If the childEntity itself is deleted from the database and what exactly happens when you call SaveChanges depends on the kind of relationship between the two: 如果将childEntity本身从数据库中删除,则调用SaveChanges时究竟发生了什么,取决于两者之间的关系类型:

If the relationship is optional, ie the foreign key that refers from the child to the parent in the database allows NULL values, this foreign will be set to null and if you call SaveChanges this NULL value for the childEntity will be written to the database (ie the relationship between the two is removed). 如果该关系是可选的,即从数据库中的子项到父项引用的外键允许使用NULL值,则该外键将设置为null,并且如果您调用SaveChanges,则childEntity的此NULL值将被写入数据库(也就是说,两者之间的关系已删除)。 This happens with a SQL UPDATE statement. 使用SQL UPDATE语句会发生这种情况。 No DELETE statement occurs. 没有发生DELETE语句。

If the relationship is required (the FK doesn't allow NULL values) and the relationship is not identifying (which means that the foreign key is not part of the child's (composite) primary key) you have to either add the child to another parent or you have to explicitly delete the child (with DeleteObject then). 如果需要该关系(FK不允许使用NULL值)并且该关系没有标识(这意味着外键不属于子级(复合)主键的一部分),则必须将子级添加到另一个父级中否则您必须显式删除该子项(然后使用DeleteObject)。 If you don't do any of these a referential constraint is violated and EF will throw an exception when you call SaveChanges - the infamous "The relationship could not be changed because one or more of the foreign-key properties is non-nullable" exception or similar. 如果您不执行任何这些操作,则将违反引用约束,并且在调用SaveChanges时EF将引发异常-臭名昭著的“由于一个或多个外键属性是不可空的,因此无法更改关系”异常或类似。

If the relationship is identifying (it's necessarily required then because any part of the primary key cannot be NULL) EF will mark the childEntity as Deleted as well. 如果该关系是可识别的(那么这是必需的,因为主键的任何部分不能为NULL),EF也会将childEntity标记为Deleted。 If you call SaveChanges a SQL DELETE statement will be sent to the database. 如果调用SaveChanges,则会将SQL DELETE语句发送到数据库。 If no other referential constraints in the database are violated the entity will be deleted, otherwise an exception is thrown. 如果没有违反数据库中的其他引用约束,则将删除该实体,否则将引发异常。

[1]: Entity Framework .Remove() vs. .DeleteObject() [1]: 实体框架.Remove()与.DeleteObject()

So i read a bunch of articles on this subject. 所以我读了很多关于这个主题的文章。 Chris's response here was really good and helpful for my understanding: Link 克里斯在这里的反应非常好,对我的理解很有帮助: 链接

But what really helped me was the small code example here: Solution . 但是真正帮助我的是这里的小代码示例: Solution

The "[Key, ForeignKey("Order"), Column(Order = 1)]" part really did the trick. “ [Key,ForeignKey(“ Order”),Column(Order = 1)]“部分确实起到了作用。

Many Thanks! 非常感谢!

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

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