我在EF6 code first
项目中使用WinForm
。
我使用以下方法从Db
读取实体,更新它们,然后将它们保存到Db
:
Linq to entities
阅读实体图表(阅读DbContext
处置后)Entity
图表。Entity
图表:
Db
DbContext
实例。Entity
Db
图表
AutoMapper
DbContext
GraphDiff
致电DbContext.SaveChanges();
将更改保留为Db
var root = new MyDbcontext()
.Roots
.LoadAggregation()
.ToList();
// LoadAggregation in this case, means following codes:
// .Include("Child1")
// .Include("Child2")
root.Child1s.Remove(child11);
root.Child1.Add(Child13); //
root.Child2.Add(Child22);
using(var uow = new UnitOfWork())
{
uow.Repository<Root>().Update(root);
uow.Repository<AnotherRoot>().Update(anotherRoot); //user may want to update multiple Roots
uow.SaveChanges(); <---- at this point Child13.Id and Child22.Id generated by Db
}
public void Update(Root entity) //Update method in my Repository class
{
var context = new MyDbcontext();
var savedEntity = context.Roots //reload entity graph from db
.LoadAggregation()
.ToList();
Mapper.Map(entity,savedEntity); // map user changes to original graph
context.UpdateGraph(savedEntity, savedEntity.MappingConfiguration); // attach updated entity to dbcontext using graphdiff
}
public void SaveChanges() // SaveChanges() in UnitofWork class
{
context.SaveChanges();
}
一切正常,
在第二张图中,用户添加了Child13和Child22,当我致电uow.SaveChanges()
时,他们将保存到Db
,并且将分配他们的Id
。但Child13.Id
对象中的Child22.Id
和entity
仍为0
,我可以手动更新Id
,但我正在寻找通用通过Id
生成Db
来更新这些Id
值的方法。
答案 0 :(得分:3)
就个人而言,我采取的方法略有不同。
这样的交易不应该跨越多个上下文。即使您可以手动更新这些ID,您也需要某种替代方法来识别这些子对象,以确保您使用数据库分配的ID正确同步对象实例。或者它可能在瞬态时更新这些对象的其他方面,并且还需要应用于数据库。一般来说,从不同的DBContexts加载的对象是不同的对象,即使它们具有相同的数据库标识,除非您在EF之上实现了某种缓存。
我做这样的事情。使用一个上下文,让EF通过注入需要执行持久性操作的上下文来管理所有标识:
var context = new MyDbcontext();
var root = context
.Roots
.LoadAggregation()
.ToList();
// LoadAggregation in this case, means following codes:
// .Include("Child1")
// .Include("Child2")
root.Child1.Remove(child11);
root.Child1.Add(Child13); //
root.Child2.Add(Child22);
using(var uow = new UnitOfWork())
{
uow.Repository<Root>().Update(root, context);
uow.Repository<AnotherRoot>().Update(anotherRoot, context); //user may want to update multiple Roots
uow.SaveChanges(context); <---- at this point Child13.Id and Child22.Id generated by Db
}
public void Update(Root entity, MyDbcontext context) //Update method in my Repository class
{
var savedEntity = context.Roots //reload entity graph from db
.LoadAggregation()
.ToList();
Mapper.Map(entity,savedEntity); // map user changes to original graph
context.UpdateGraph(savedEntity, savedEntity.MappingConfiguration); // attach updated entity to dbcontext using graphdiff
}
public void SaveChanges(context) // SaveChanges() in UnitofWork class
{
context.SaveChanges();
}
如果由于某种原因您无法使用相同的上下文,您可能需要考虑在子对象(例如Guid)中添加某种其他标识字段,然后将其写入子对象之前通过SaveChanges持久回到数据库。至少你有一个相当一致的方法来识别同步对象。