0

I'm trying to update a one-to-many relationship with EntityFramework, but EF won't save the relationship for some reason. I'm using ASP.Net MVC, but that does not seem to matter in this case as the data is received correctly.

I've tried a lot of possible solutions and some tutorials, unfortunately almost all of them describe a scenario where the connection is made via a foreign key property in the class itself.(I'm aware that EF adds a FK in the database, but i cant access that directly.) My approach seems to be significantly different as none of their solution seems to work for me.

The code below seems to me to be the most promising, but it still doesn't work. the foreign key of the activity object doesn't get updated.

Removing context.Entry(act.ActivityGroup).State = EntityState.Detached; causes a Primary Key collision, as EF tries to insert the ActivityGroup as a new Entity. Marking it as Modified, doesn't do the trick either.

Models:

public class Activity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public Guid ActivityID { get; set; }
    public string Name { get; set; }
    public ActivityGroup ActivityGroup { get; set; }
}


public class ActivityGroup
{
    public int ActivityGroupID { get; set; }
    public string GroupName { get; set; }
    public string BackgroundColor { get; set; }
}

Method to save Data

public ActionResult SaveActivities(List<Activity> activities)
{
    if (ModelState.IsValid)
    {
        using (TSSDBContext context = new TSSDBContext())
        {
            foreach (Activity act in activities)
            {
                if (act.ActivityGroup != null)
                {
                      context.Entry(act.ActivityGroup).State = EntityState.Detached;
                }
                context.Entry(act).State = (act.ActivityID == null || act.ActivityID == Guid.Empty) ? EntityState.Added : EntityState.Modified;
            }
            context.SaveChanges();
            return new HttpStatusCodeResult(200);
        }
    }else
    {
        return new HttpStatusCodeResult(500);
    }

}
Kendoha
  • 3
  • 2
  • 2
    you are not changing anything – Eldho May 31 '16 at 13:34
  • Instead of setting the ActivityGroup to Detached, set it to Unchanged. Otherwise, what you have here should work. It's a bit out-of-the-ordinary to use the Entry method instead of the DbSet collections inside of the DbContext, but that's up to you. – Spivonious May 31 '16 at 15:37
  • I found the problem, I tried to apply changes to the database by adding new objects with new data(including the valid PK) to the context and marking them as Modified. Not knowing that is not how its supposed to be done. I had to load the entity from the database, apply my changes to the loaded object and then mark the database entity as modified. for some reason my faulty approach worked in another part of the program... – Kendoha May 31 '16 at 19:35

1 Answers1

1

You could try something like this.

EF context is tracking each entity you don't need manually marking entities , Modified or Added for each. Read about Entityframework context tracking

Just fetch the entities what you need and decide to insert or update on based on your condition and just Add what should be added and update
Just do a SaveChanges EF will show the magic

This is a basic idea of inserting and updating entities at one shot. If you have concerns about performance i would suggest you to update using AddRange method in EF 6.0

  using(var db1 = new Entities1())
  {
      var activitylists = db.Activity.ToList();

      foreach (var item in activitylists )
      {
          if(item.Id==null)
          {
              var newActivity= new Activity();
             //Your entities 
             newActivity.Name="Name";
             db.Activity.Add(newActivity);
             db.Entry<Activity>(item).State = System.Data.Entity.EntityState.Added;
          }
          else
          {
            item.Name="new name update";
           db.Entry<Activity>(item).State = System.Data.Entity.EntityState.Modified;
          }

       }
       db.SaveChanges();
   }

Update : if your getting data from PostRequest , you need to manually mark the entities as modified or added as the context is not aware of what to do with entities

Community
  • 1
  • 1
Eldho
  • 6,426
  • 3
  • 38
  • 66
  • I totally fail to see how this addresses my problem. I dont need to load a list of Items from the db, i get a list of modified/new items via the post request. I just want to insert/update them into the db. but i just found out, that its not just the relationship thats not getting updated, nothing gets updated, which confuses me because i'm running basically the same code somewhere else and there it works. – Kendoha May 31 '16 at 14:14
  • I have updated the answer, If the same code is working ? But you have not changed on any property out here – Eldho May 31 '16 at 14:21
  • I'm getting Data from the Post request, as you can see in my code i am marking it as modified but the thought just crossed my mind: is my Problem here, that I try to insert data EF can not understand when im just throwing objects at the context expecting EF will accept them? and what i should do, is to load the objects from the db and apply the changes to them? – Kendoha May 31 '16 at 15:42
  • Thank you very much, you were right, I just didnt get the critical point right away. – Kendoha May 31 '16 at 19:57