I try to find best solution to the problem while updating entity which has deep relationships. Because my entities are too complex and have deeper relationships, I simplified into this.
MainCategory - Category has one-to-many relationship and Category - SubCategory has also one-to-many relationship
public class MainCategory
{
[Key]
public int Id { get; set; }
public string MainCategoryName { get; set; }
public virtual ICollection<Category> Categories { get; set; }
}
public class Category
{
[Key]
public int Id { get; set; }
public string CategoryName { get; set; }
public virtual ICollection<SubCategory> SubCategories { get; set; }
}
public class SubCategory
{
[Key]
public int Id { get; set; }
public string SubCategoryName { get; set; }
public Category Category { get; set; }
}
Here is how I handle the situation while updated or new MainCategory entity with child and grandchild records comes from somewhere.
public void AddOrUpdateMainCategory()
{
using (var ctx = new MyContext())
{
// Gets MainCategory domain object.
// Domain object has no id property because it does not come from (ctx.MainCategories)
var mainCategory = GetMainCategory();
var mainCategoryFromDb = ctx.MainCategory.Include(x => x.Categories.Select(y => y.SubCategories)).FirstOrDefault(x => someCondition());
if (mainCategoryFromDb == null)
{
ctx.ShopParameterPeriodItems.Add(mainCategory);
}
// If mainCategoryFromDb is not null, mainCategory object should map to mainCategoryFromDb.
else
{
ctx.SubCategories.RemoveRange(mainCategoryFromDb.Categories.SelectMany(x => x.SubCategories));
ctx.Categories.RemoveRange(mainCategoryFromDb.Categories);
ctx.MainCategories.Remove(mainCategoryFromDb);
ctx.MainCategories.Add(mainCategory);
}
ctx.SaveChanges();
}
}
Problems of code
- Because updating mechanism is deleting old entity and its child and grandchild entities and adding a new one, Id value of database records are refreshed every time. This would be a big problem if any foreign key exists to MainCategory, Category, or SubCategory from different tables.
The first problem can be solved like that
foreach (var category in mainCategoryFromDb.Categories) { foreach (var subCategory in category.SubCategories) { // Set subCategory properties } // Set category properties } // Set mainCategoryFromDb properties
This solves Id loss problem but as I wrote, entities are very complex. It would be hard to maintain and we do not know, for example, which category of mainCategory will update category of mainCategoryFromDb because mainCategory and its child and grandchild entities do not have Id property.
What I am looking for is a way to solve the problems.