Question

I am trying to delete some data (how hard can it be, anyway?) but whenever I remove a complex-type prop from my model object, the contents of an ICollection prop are also mixed. Here's the code:

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

Before I fire off the line with

db.WeekSpecs.Remove(schedule.WeekSpec);

ExceptionHoursSets has, say, three items. After removing the WeekSpec, it has zero. Eh. Any ideas?

Update

Here's the code for the HoursDb class:

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

Also, should it help, DaySpecs contain open and close hours for a generic building; they are contained in WeekSpecs.
The Schedule contains a WeekSpec to describe the general open hours, as well as a set of ExceptionHoursSets.
These have WeekSpecs describing exceptions to the aforementioned general hours.

Was it helpful?

Solution 2

Moving the foreach that deletes the ExceptionHoursSets to the front after the var schedule is initialized, as well as removing all but the last db.SaveChanges, seems to work. I still do not know why it does and what I had doesn't, though, so any additional information is appreciated.

OTHER TIPS

My guess that in Database for relationship between WeekSpec and ExceptionHoursSet you have the cascade delete option enabled. So when you delete WeekSpec - you delete the same WeekSpec that you have in ExceptionHoursSet, and because you have cascade delete - EF deletes ExceptionHoursSet objects as well.

More than I think that this will be the right solution to use Cascade Delete option for relationship and do not use foreach to delete all child objects. Of course - you should use it only if you 100% sure that it is impossible to have WeekSpecs/ExceptionHoursSet/DaySpecs without Schedules.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top