Search code examples
c#asp.netentity-frameworkforeign-key-relationship

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:

    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.

I think that i'm missing something related to the access to the Act model.

Will appreciate any help, Yuval.


Solution

  • 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.

    The "[Key, ForeignKey("Order"), Column(Order = 1)]" part really did the trick.

    Many Thanks!