I tried loading the navigation properties first by using Include
, and I ensured that the children were loaded.
For new items, I can add a child navigation set with no issues. For updated items, I tried to pass in a completely new collection to overwrite the list, but I read that I needed to work with the loaded collection. Even after clearing the collection and adding to it, I do not see any changes reflected.
For all entities in my project, I am calling a generic method which has these lines and some error handling logic, but no errors are thrown:
Save() method:
context.Set<T>().AddOrUpdate(entities);
context.SaveChanges();
Use:
var entities = repository.LoadWithIncludes(x =>.Subset1);
var entity = entities.FirstOrDefault(x => x.ID == id) ?? new Entity{ID = id};
entity.Subset1.Clear();
var IDs = GetIDs(id) ?? Array.Empty<int?>();
foreach (var id in IDs)
{
entity.Subset1.Add(new Subset
{
ParentId = id,
Value = part1;
});
}
// then I pass the new and updated items into an array and call the Save() method above
The LoadWithIncludes method is taken from this answer: https://stackoverflow.com/a/18805096/7096114
AddOrUpdate
MethodThis method is supposed to be used when seeding your database. Which leads me to think you're going to get some poor behaviors.
Let's go start with correcting the way you are updating the context...
public void Edit(Entity entity)
{
var db = context
.Include(i => i.Subset1)
.Where(i => i.ID == id)
.Single();
// update entity
context.Entry(db).CurrentValues.SetValues(entity);
// delete / clear subset1 from database
foreach (var dbSubset1 in db.Subset1.ToList())
{
if (!entity.Subset1.Any(i => i.ID == dbSubset1.ID))
context.Subset1.Remove(dbSubset1);
}
foreach (var newSubset1 in entity.Subset1)
{
var dbSubset1 = db.Subset1.SingleOrDefault(i => i.ID == newSubset1.Id);
if (dbSubset1 != null)
// update Subset1
context.Entry(dbSubset1).CurrentValues.SetValues(newSubset1);
else
db.Subset1.Add(newSubset1);
}
// save
db.SaveChanges();
}
There is a great article on how to get this done in a much cleaner way, which involves making a method just to deal with the navigation property in the Microsoft Docs here (look about 3/4 of the way down the article for the example).
Here is also a quote from the docs.
For most relationships, this can be done by updating either foreign key fields or navigation properties. For many-to-many relationships, the Entity Framework doesn't expose the join table directly, so you add and remove entities to and from the appropriate navigation properties.