【问题标题】:Entity framework 6 Concept clear regarding Remove, RemoveRange, EntityState.Deleted实体框架 6 关于 Remove、RemoveRange、EntityState.Deleted 的概念清晰
【发布时间】:2018-08-28 19:08:22
【问题描述】:

我在我的项目中使用 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; }
}

现在我必须从数据库中删除课程及其所有引用实体。例如,如果课程正在删除,则其属性如 AssignedCustomersLicenses 等都必须删除。

但我不明白使用实体框架的一件事。

对于从数据库中删除实体,我们有多个选项,例如。

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

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

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

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

【问题讨论】:

  • 它给了你什么确切的错误?
  • @CamiloTerevinto 我已经更新了我的问题

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


【解决方案1】:

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

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

【讨论】:

  • 我明白你在说什么。但问题是我不明白为什么有时 Remove 有效,有时无效。假设您看到我上面的课程与其他所有实体都有适当的关系。当我首先删除课程的主要实体时,我没有删除其相关实体。如果我使用 Remove 方法从 List 中删除一个对象,则它不起作用,但是当我使用 context.CustomerCourses.RemoveRange 时,它​​确实可以正常工作而没有任何错误。这是为什么?如果我在 foreach 循环中使用 .Remove 方法,它与从上下文中删除有什么不同吗?
  • 这几行代码有什么区别?下面的方法只有第一种方法可以无缝工作,但其他两种方法不能。为什么? _context.CustomerCourses.RemoveRange(currentCourse.AssignedCustomers); currentCourse.AssignedCustomers.ToList().ForEach(ac => { currentCourse.AssignedCustomers.Remove(ac): }); currentCourse.AssignedCustomers.ToList().ForEach(ac => { _context.Entry(ac).State = EntityState.Deleted; });
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-26
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
相关资源
最近更新 更多