实体框架6关于Remove,RemoveRange,EntityState.Deleted

时间:2018-08-28 19:08:23

标签: c# entity-framework entity-framework-6

我在项目中使用了Entity Framework 6,对于使用EF删除对象的某些概念,我始终有疑问。

我仍然不知道哪种情况在哪种情况下有效。我只是尝试全部,如果可以的话,我将其保留直到代码正常工作。但是,没有人需要一劳永逸地理解这个概念。我做了研究,无法清楚地理解这个概念。

我在EF中有一个域类,它具有多个引用实体。例如。我有一个名为 Course 的域类,它在代码中有下面提到的多个引用对象。

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

现在,我必须从数据库中删除所有带有其引用实体的课程。例如,如果课程正在删除,则必须删除其所有属性,如 AssignedCustomers 许可证等。

但是我对使用实体框架一无所知。

要从数据库中删除实体,我们有多种选择。

Remove
RemoveRange
EntityState.Deleted

有时,Remove起作用,但有时,RemoveRange起作用,有时是Entitystate.Deleted起作用。为什么?

我的代码用于删除课程

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;

有时删除范围有效并且代码成功运行

_context.CustomerCourses.RemoveRange(currentCourse.AssignedCustomers);

下面的代码行给我错误,但在其他情况下它为什么起作用?

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

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

谁能向我解释在哪种情况下我应该使用什么?

我大部分时间收到的错误是

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.

当我使用这段代码时出现此错误

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

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

OR

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

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

之后,当我点击SaveChanges时出现错误。

1 个答案:

答案 0 :(得分:0)

您需要在架构和Entity Framework中设置级联规则,以使它知道在删除课程时将删除哪些相关实体。例如,您将要级联删除,而像Learner这样的其他人则可能具有可为空的键,如果课程被删除,则可以将其清除。

只要它设置正确,您只需要使用:context.Courses.Remove(course);,相关实体将被自动删除或取消关联。从一个简单的父子关系示例开始,一个孩子级联删除,另一个孩子与可空FK取消关联。您当前的示例似乎还具有多对多关联(GroupCourses),因此,根据映射/关系,方法将有所不同。