Структура сущности 6 Понятие, ясное относительно Удаления, RemoveRange, EntityState.Deleted - PullRequest
0 голосов
/ 28 августа 2018

Я использую 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 , Licenses и т. Д., Все должны быть удалены.

Но я не понимаю одну вещь, используя Entity Framework.

Для удаления объекта из БД у нас есть несколько вариантов, например.

Remove
RemoveRange
EntityState.Deleted

Иногда Remove работает, но иногда RemoveRange Works и иногда 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 голосов
/ 29 августа 2018

Вам необходимо настроить правила каскада в вашей схеме и в Entity Framework, чтобы она знала, какие связанные объекты будут удалены при переходе на удаление курса. Например, вы захотите каскадно удалить, в то время как другие, такие как Learner, вероятно, будут иметь нулевой ключ, который можно очистить, если курс удален.

При условии, что он настроен правильно, вам просто нужно использовать: context.Courses.Remove(course);, и связанные с ним объекты будут удалены или отключены автоматически. Начните с более простого примера ваших родительско-дочерних отношений: один дочерний для каскадного удаления, другой для диссоциации с обнуляемым FK. В вашем текущем примере также есть связи «многие ко многим» (GroupCourses), поэтому подход в зависимости от сопоставления / отношений будет различным.

...