Kendoha
Kendoha

Reputation: 3

Updating Entity Framework many-to-one Relationship

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

}

Upvotes: 0

Views: 2231

Answers (1)

Eldho
Eldho

Reputation: 8301

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

Upvotes: 1

Related Questions