Entity framework 6 Concept clear regarding Remove, RemoveRange, EntityState.Deleted

c# entity-framework entity-framework-6

Question

I use Entity framework 6 in my projects and I always have doubts regarding some of the concepts which are used to delete objects using EF.

I still don't know which one works in which scenario. I just try all and if one works I leave it until the code is working. But no wi need to understand this concept once and for all. I did my research my unable to understand the concept clearly.

I have a domain class in EF which have multiple referencing entities. For example. I have a domain class called Course and It has multiple referencing objects mentioned below in the code.

public class Course
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }

        public int CompanyId { get; set; }
        public virtual Company Company { get; set; }

        public virtual PricingSchedule PricingSchedule { get; set; }
        public virtual ICollection<CustomerCourse> AssignedCustomers { get; set; }

        public virtual ICollection<License> Licenses { get; set; }
        public virtual ICollection<GroupLicense> GroupLicenses { get; set; }
        public virtual ICollection<GroupCourse> GroupCourses { get; set; }
        public virtual ICollection<Learner> Learners { get; set; }
}

Now I have to delete the course from the DB with all of its referencing entities. For example, If the course is deleting then its properties like AssignedCustomers, Licenses etc all must be deleted.

But I don't understand one thing using Entity framework.

For deleting an entity from DB we have multiple options like.

Remove
RemoveRange
EntityState.Deleted

Sometimes Remove works but sometime RemoveRange Works and sometime Entitystate.Deleted works. Why?

My code is for deleting a Course

var courses = _context.Courses
                                              .Include("AssignedCustomers")
                                              .Include("PricingSchedule")
                                              .Include("Licenses")
                                              .Include("GroupCourses")
                                              .Include("GroupLicenses")
                                              .Where(e => courseIds.Contains(e.Id)).ToList();
                        if (courses != null && courses.Count > 0)
                        {
                            courses.ForEach(currentCourse =>
                            {

                                _context.Entry(currentCourse.PricingSchedule).State = EntityState.Deleted;

Sometime remove range works and code run successfully

_context.CustomerCourses.RemoveRange(currentCourse.AssignedCustomers);

Below line of code gives me error but in other scenario it works why?

 //currentCourse.AssignedCustomers.ToList().ForEach(ac =>
                    //{
                    //    //currentCourse.AssignedCustomers.Remove(ac);
                    //    _context.Entry(ac).State = EntityState.Deleted;
                    //});

                    _context.Entry(currentCourse).State = EntityState.Deleted;
                });
            }
            _context.SaveChanges();

Can anyone explain to me the difference in which situation I should use what?

The error I receive most of the time is

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.

This error comes up when I use this piece of code

 currentCourse.AssignedCustomers.ToList().ForEach(ac =>
                        {

                            _context.Entry(ac).State = EntityState.Deleted;
                        });

OR

 currentCourse.AssignedCustomers.ToList().ForEach(ac =>
                            {

                                currentCourse.AssignedCustomers.Remove(ac):
                            });

after that when I hit SaveChanges The error comes up.

1
0
8/28/2018 7:21:40 PM

Popular Answer

You need to set up the cascade rules in your schema and within Entity Framework so that it knows which related entities will be deleted when you go to delete a course. For instance you will want to cascade delete while others like Learner would likely have a null-able key which can be cleared if a course is removed.

Provided it is set up correctly, you should just need to use: context.Courses.Remove(course); and the related entities will be removed or disassociated automatically. Start with a simpler example of your parent-child relationships, one child to cascade delete, another to disassociate with a nullable FK. Your current example looks to also have many-to-many associations (GroupCourses) so depending on the mapping/relationships the approach will vary.

0
8/28/2018 10:11:09 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow