0

I have a object called BandyProfile and in my service layer I modify the profile and save.

public void SaveProfile(string userId, System.Collections.Specialized.NameValueCollection request)
{
        BandyProfile bandyProfile = _bandyProfileRepository.Find(userId);

        bandyProfile.CatchPhrase = request[0];
        bandyProfile.StartedPracticing = Convert.ToInt16(request[1]);
        bandyProfile.Education = request[2];
        bandyProfile.Work = request[3];
        bandyProfile.WhyIPractice = request[4];
        bandyProfile.Inspirations = request[5]; 
        bandyProfile.IsATeacher = Convert.ToBoolean(request[6]);
        bandyProfile.TrainingCertification = request[7];
        bandyProfile.YogaClasses = GetSelectedClasses(request[8]);
        bandyProfile.StartedTeaching = Convert.ToInt16(request[9]);
        bandyProfile.WhyITeach = request[10];

        _bandyProfileRepository.Save();
}

YogaClasses is a ICollection of YogaClass

public class YogaClass
{
    public int YogaClassId { get; set; }
    public YogaStyle YogaStyle { get; set;}

    [Index]
    [Required]
    public string BandyProfileRefId { get; set; }

    [ForeignKey("BandyProfileRefId")]
    public virtual BandyProfile.BandyProfile BandyProfile { get; set; }
}

PROBLEM - when I add initial yogaclasses and save I'm fine, but when I modify(remove some and add some) yogaclasses and save, all the old entries don't get deleted from the table. They remain in the database and new entries get written into new rows.

QUESTION - Can I remove all the old "YogaClasses" entries for the BandyProfile without calling the YogaClass table directly? I thought Entity Framework would see what changes have been made and do some magic under the hood!

_bandyProfileRepository.Save();

does a context.SaveChanges()

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
chuckd
  • 13,460
  • 29
  • 152
  • 331

1 Answers1

0

This is because your YogaClass object needs to create a composite primary key using both the YogaClassId and the BandyProfileRefId.

When you remove a YogaClass from your ICollection the BandyProfileRefId will be null which violates your primary key constraint and marks the object for deletion.

See: Entity Framework .Remove() vs. .DeleteObject()

Data annotations: (I think this is the correct syntax)

public class YogaClass
{
    [Key]
    public int YogaClassId { get; set; }
    public YogaStyle YogaStyle { get; set;}

    [Key]
    public string BandyProfileRefId { get; set; }

    [ForeignKey("BandyProfileRefId")]
    public virtual BandyProfile.BandyProfile BandyProfile { get; set; }
}

Fluent Api:

public class MyDbContext : DbContext
{
    public MyDbContext()
        : base("DbContext")
    {
    }

    public DbSet<BandyProfile> BandyProfiles { get; set; }
    public DbSet<YogaClass> YogaClasses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<YogaClass>()
            .HasKey(yogaClass => new {yogaClass.YogaClassId, yogaClass.BandyProfileRefId});

        base.OnModelCreating(modelBuilder);
    }
}
Community
  • 1
  • 1
Dan
  • 968
  • 1
  • 8
  • 21