MVC удалить удаление несвязанных данных

Я пытаюсь удалить некоторые данные (в любом случае, насколько это сложно?), но всякий раз, когда я удаляю реквизит сложного типа из объекта моей модели, содержимое реквизита ICollection также смешивается. Вот код:

    [HttpPost, ActionName("Delete")]
    public ActionResult DeleteConfirmed(string name)
    {
        using (var db = new HoursDb())
        {
            db.Configuration.ProxyCreationEnabled = false;

            var schedule = db.Schedules.Where(s => s.ScheduleId == name)
                .Include(s => s.WeekSpec)
                .Include(s => s.WeekSpec.DaySpecs)
                .Include(s => s.ExceptionHoursSets)
                .Include(s => s.ExceptionHoursSets.Select(e => e.WeekSpec))
                .Include(s => s.ExceptionHoursSets.Select(e => e.WeekSpec.DaySpecs))
                .FirstOrDefault();
            if (schedule == null)
            {
                return View("404");
            }


            var daySpecs = new List<DaySpec>(schedule.WeekSpec.DaySpecs);
            foreach (var daySpec in daySpecs)
            {
                db.DaySpecs.Remove(daySpec);
            }
            db.WeekSpecs.Remove(schedule.WeekSpec);

            var exceptionHoursSets = new List<ExceptionHoursSet>(schedule.ExceptionHoursSets);
            foreach (var exceptionHoursSet in exceptionHoursSets)
            {
                daySpecs = new List<DaySpec>(exceptionHoursSet.WeekSpec.DaySpecs);
                foreach (var daySpec in daySpecs)
                {
                    db.DaySpecs.Remove(daySpec);
                    db.SaveChanges();
                }
                db.WeekSpecs.Remove(exceptionHoursSet.WeekSpec);
                db.SaveChanges();
                db.ExceptionHoursSets.Remove(exceptionHoursSet);
            }

            db.Schedules.Remove(schedule);
            db.SaveChanges();

            return RedirectToAction("Index");
        }
    }

Прежде чем я сброшу линию с

db.WeekSpecs.Remove(schedule.WeekSpec);

ExceptionHoursSets содержит, скажем, три элемента. После удаления WeekSpec он равен нулю. Эх. Любые идеи?

Обновлять

Вот код класса HoursDb:

using System.Data.Entity;
using LibraryAdmin.Models;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace ####.DAL
{
    public class HoursDb : DbContext
    {
        public DbSet<DaySpec> DaySpecs { get; set; }
        public DbSet<WeekSpec> WeekSpecs { get; set; }
        public DbSet<ExceptionHoursSet> ExceptionHoursSets { get; set; }
        public DbSet<Schedule> Schedules { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}

Кроме того, если это поможет, DaySpecs содержит часы работы и закрытия для типового здания; они содержатся в WeekSpecs.
Расписание содержит WeekSpec для описания общих часов работы, а также набор ExceptionHoursSets.
У них есть WeekSpecs, описывающие исключения из вышеупомянутых общих часов.


person Bondolin    schedule 15.08.2012    source источник
comment
Что такое HoursDb? это контекст базы данных EF? или просто самодельный образец репозитория? Я думаю, что реляционная БД удаляет ее на основе внешних ключей.   -  person Rikon    schedule 15.08.2012
comment
@Rikon - это Code First DbContext. Я добавлю код.   -  person Bondolin    schedule 15.08.2012


Ответы (2)


Я предполагаю, что в базе данных для связи между WeekSpec и ExceptionHoursSet у вас включена опция каскадного удаления. Таким образом, когда вы удаляете WeekSpec, вы удаляете тот же WeekSpec, что и в ExceptionHoursSet, а поскольку у вас есть каскадное удаление, EF также удаляет объекты ExceptionHoursSet.

Более чем я думаю, что это будет правильное решение для использования опции Cascade Delete для отношений и не использовать foreach для удаления всех дочерних объектов. Конечно - вы должны использовать его, только если вы на 100% уверены, что невозможно иметь WeekSpecs/ExceptionHoursSet/DaySpecs без расписаний.

person outcoldman    schedule 15.08.2012
comment
Каскадное удаление может иметь какое-то отношение к этому. Я не понимаю, почему это может вызвать проблему при удалении WeekSpec в моем вопросе, так как это опора расписания, а не наборы исключений расписания (см. мой обновленный обзор структуры), поэтому, конечно, я также не хочу это каскадное удаление. Как я могу быть уверен, что этого не произойдет? - person Bondolin; 15.08.2012
comment
Вы должны попытаться использовать SQL Profiler, чтобы посмотреть, какие SQL-запросы .NET пытаются выполнить в каждой строке вашего кода. Это может дать вам некоторые ответы. - person outcoldman; 15.08.2012
comment
Не знаю, смогу ли я использовать его или нет, но спасибо за помощь. - person Bondolin; 15.08.2012

Перемещение foreach, удаляющего ExceptionHoursSets, на передний план после инициализации расписания var, а также удаление всего, кроме последнего db.SaveChanges, кажется, работает. Я до сих пор не знаю, почему это происходит, а то, что у меня было, нет, поэтому любая дополнительная информация приветствуется.

person Bondolin    schedule 15.08.2012