繁体   English   中英

尝试级联删除时出错

[英]Error while trying to cascade-delete

尝试从数据库中删除项目时,出现以下错误消息:

操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。 对关系进行更改时,相关的外键属性将设置为空值。 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

我已经阅读了许多有关此问题的主题,但是似乎没有一个对您有帮助的(或者也许我不太了解它们)。

我的模型是:

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; }
}

我还定义了一个流畅的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>()

        }

控制器中的方法:

        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();                                                           
            }                
        }
    }

我尝试使用代码优先方法将“ ARDOperationId”属性定义为可为空(int?),并且我没有通过这种方式得到任何错误,但是子级的数据仍然保留在DB中。

我认为我缺少与访问该法案模型有关的内容。

谢谢您的帮助,尤瓦尔。

看看EF专家关于remove方法的[this answer] [1]。

EntityCollection.Remove(childEntity)将parent和childEntity之间的关系标记为Deleted。 如果将childEntity本身从数据库中删除,则调用SaveChanges时究竟发生了什么,取决于两者之间的关系类型:

如果该关系是可选的,即从数据库中的子项到父项引用的外键允许使用NULL值,则该外键将设置为null,并且如果您调用SaveChanges,则childEntity的此NULL值将被写入数据库(也就是说,两者之间的关系已删除)。 使用SQL UPDATE语句会发生这种情况。 没有发生DELETE语句。

如果需要该关系(FK不允许使用NULL值)并且该关系没有标识(这意味着外键不属于子级(复合)主键的一部分),则必须将子级添加到另一个父级中否则您必须显式删除该子项(然后使用DeleteObject)。 如果您不执行任何这些操作,则将违反引用约束,并且在调用SaveChanges时EF将引发异常-臭名昭著的“由于一个或多个外键属性是不可空的,因此无法更改关系”异常或类似。

如果该关系是可识别的(那么这是必需的,因为主键的任何部分不能为NULL),EF也会将childEntity标记为Deleted。 如果调用SaveChanges,则会将SQL DELETE语句发送到数据库。 如果没有违反数据库中的其他引用约束,则将删除该实体,否则将引发异常。

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

所以我读了很多关于这个主题的文章。 克里斯在这里的反应非常好,对我的理解很有帮助: 链接

但是真正帮助我的是这里的小代码示例: Solution

“ [Key,ForeignKey(“ Order”),Column(Order = 1)]“部分确实起到了作用。

非常感谢!

暂无
暂无

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

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