使用Slauma的解决方案,我创建了一些通用函数来帮助更新子对象和子对象集合。
我的所有持久化对象都实现了这个接口。
public interface IBase
{
int Id { get; set; }
}
通过这个,我在我的代码库中实现了这两个函数。
public T AddOrUpdateEntry<T>(DbSet<T> set, T entry, T orgEntry) where T : class, IBase
{
if (entry.Id == 0 || orgEntry == null)
{
entry.Id = 0;
return set.Add(entry);
}
else
{
Context.Entry(orgEntry).CurrentValues.SetValues(entry);
return orgEntry;
}
}
public void AddOrUpdateCollection<T>(DbSet<T> set, ICollection<T> newList, ICollection<T> orgList) where T : class, IBase
{
foreach (T entry in newList)
{
var orgEntry = orgList.SingleOrDefault(e => e.Id != 0 && e.Id == entry.Id);
AddOrUpdateEntry(set, entry, orgEntry);
}
foreach (T orgEntry in orgList.Where(e => e.Id != 0).ToList())
{
if (!newList.Any(e => e.Id == orgEntry.Id))
{
set.Remove(orgEntry);
}
}
}
使用它的方法如下:
var originalParent = _dbContext.ParentItems
.Where(p => p.Id == parent.Id)
.Include(p => p.ChildItems)
.Include(p => p.ChildItems2)
.SingleOrDefault();
originalParent = AddOrUpdateEntry(_dbContext.ParentItems, parent, originalParent);
AddOrUpdateCollection(_dbContext.ChildItems, parent.ChildItems, orgiginalParent.ChildItems);
AddOrUpdateCollection(_dbContext.ChildItems2, parent.ChildItems2, orgiginalParent.ChildItems2);
希望这能有所帮助
额外提示:您也可以创建一个单独的 DbContextExtentions(或自己的上下文接口)类:
public static void DbContextExtentions {
public static T AddOrUpdateEntry<T>(this DbContext _dbContext, DbSet<T> set, T entry, T orgEntry) where T : class, IBase
{
if (entry.IsNew || orgEntry == null)
{
entry.Id = 0;
return set.Add(entry);
}
else
{
_dbContext.Entry(orgEntry).CurrentValues.SetValues(entry);
return orgEntry;
}
}
public static void AddOrUpdateCollection<T>(this DbContext _dbContext, DbSet<T> set, ICollection<T> newList, ICollection<T> orgList) where T : class, IBase
{
foreach (T entry in newList)
{
var orgEntry = orgList.SingleOrDefault(e => e.Id != 0 && e.Id == entry.Id);
AddOrUpdateEntry(_dbContext, set, entry, orgEntry);
}
foreach (T orgEntry in orgList.Where(e => e.Id != 0).ToList())
{
if (!newList.Any(e => e.Id == orgEntry.Id))
{
set.Remove(orgEntry);
}
}
}
}
并像这样使用它:
var originalParent = _dbContext.ParentItems
.Where(p => p.Id == parent.Id)
.Include(p => p.ChildItems)
.Include(p => p.ChildItems2)
.SingleOrDefault();
originalParent = _dbContext.AddOrUpdateEntry(_dbContext.ParentItems, parent, originalParent);
_dbContext.AddOrUpdateCollection(_dbContext.ChildItems, parent.ChildItems, orgiginalParent.ChildItems);
_dbContext.AddOrUpdateCollection(_dbContext.ChildItems2, parent.ChildItems2, orgiginalParent.ChildItems2);
int?
以匹配数据库,问题得到解决。 - redwards510