我尝试在更新具有深层关系的实体时找到问题的最佳解决方案。因为我的实体太复杂而且关系更深,所以我简化了这个。
MainCategory - 类别具有一对多关系,而类别 - 子类别也具有一对多关系
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; }
}
以下是我在更新时处理这种情况的方法,或者具有子孙记录的新MainCategory实体来自某个地方。
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();
}
}
第一个问题可以像那样解决
foreach (var category in mainCategoryFromDb.Categories)
{
foreach (var subCategory in category.SubCategories)
{
// Set subCategory properties
}
// Set category properties
}
// Set mainCategoryFromDb properties
这解决了 Id loss 问题,但正如我所写,实体非常复杂。它很难维护,我们不知道,例如, mainCategory 的哪个类别将更新 mainCategoryFromDb 的类别,因为mainCategory及其子孙实体没有Id属性。
我正在寻找的是一种解决问题的方法。
答案 0 :(得分:0)
您的问题是您正在使用断开连接的实体,因此DbContext
不会监视它们的更改。因此,您需要做的是在被删除的方案中自己跟踪更改,稍后当您将它们附加回DbContext
时,根据跟踪的更改为每个实体设置正确的状态。
没有用于跟踪更改的fiex解决方案,但是,要将更改发送到数据库,您只需将根对象附加到上下文,然后设置每个跟踪实体的状态。
请参阅How to use DBContext.Add/Attach (using EF CodeFirst 4.1) with nested opbjects。这显示了附加和设置状态的基本方式。然后,您只需设置不同的状态,Unchanged
除外,此问答显示在此问答语中。