尝试级联删除时出错

时间:2015-01-27 07:35:03

标签: c# asp.net entity-framework foreign-key-relationship

我在尝试从db中删除项目时收到以下错误消息:

  

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

我已经阅读了很多关于这个问题的主题,但是它们似乎都没有帮助(或者我可能不太了解它们)。

我的模特是:

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”属性定义为nullable(int?)并且我没有以这种方式获得任何错误,但是孩子的数据仍然保留在数据库中。

我认为我遗漏了与访问Act模式相关的内容。

非常感谢任何帮助, 尤瓦。

2 个答案:

答案 0 :(得分:0)

看一下EF大师关于删除方法的[这个答案] [1]。

  

EntityCollection.Remove(childEntity)标记之间的关系   parent和childEntity已删除。如果childEntity本身是   从数据库中删除以及调用时到底发生了什么   SaveChanges取决于两者之间的关系类型:

     

如果关系是可选的,即引用的外键   数据库中父节点的子节点允许NULL值,这个   foreign将被设置为null,如果你调用SaveChanges这个NULL   childEntity的值将被写入数据库(即   两者之间的关系被删除)。这种情况发生在SQL上   更新声明。没有DELETE语句。

     

如果需要关系(FK不允许NULL值)和   关系不是识别(这意味着外键   不必是孩子的(复合)主键的一部分   将子项添加到另一个父项或您必须显式删除   child(然后使用DeleteObject)。如果你不做这些中的任何一个   违反了引用约束,EF将抛出异常   你打电话给SaveChanges - 臭名昭着的&#34;关系不可能   因为一个或多个外键属性而更改   不可为空&#34;例外或类似。

     

如果关系正在确定(那么必然需要)   因为主键的任何部分都不能为NULL)EF会标记   childEntity也被删除了。如果您调用SaveChanges SQL DELETE   语句将被发送到数据库。如果没有其他参考   违反了数据库中的约束,实体将被删除,   否则会引发异常。

     

[1]:   Entity Framework .Remove() vs. .DeleteObject()

答案 1 :(得分:0)

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

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

&#34; [Key,ForeignKey(&#34; Order&#34;),Column(Order = 1)]&#34;部分确实做到了。

非常感谢!