我如何让Entity Framework与我分离的对象图一起工作?
问题描述:
在我的应用程序中,我们为每个HTTP请求获取我们的DbContext
的新实例。在正常的工作流程,我们创建一个实体,并开始填充它部分的导航性能:我如何让Entity Framework与我分离的对象图一起工作?
// Request 1
var foo = new Foo();
SessionStore.Add("Foo", foo);
// Request 2
var bar = BarDataService.GetBar(barId);
var foo = SessionStore.Get<Foo>("Foo");
foo.Bars.Add(bar);
// Request 3
var baz = BazDataService.GetBaz(bazId);
var foo = SessionStore.Get<Foo>("Foo");
foo.Baz = baz;
一旦对象图被完全填充,我们插入实体到数据库:
var foo = SessionStore.Get<Foo>("Foo");
FooDataService.Add(foo); // BOOM!
的添加通常只是增加了实体到DbSet
,然后调用保存更改:
Set.Add(entity);
Context.SaveChanges();
显然,这由于失败的事实,foo
对象包含多个代理对象,每个代理对象都连接到不同的DbContexts
。我们决定在是分离的对象,我们是接受的解决方案:对于事实,这现在创建Bar
和Baz
对象的新实例
// Request 2 (modified)
var bar = BarDataService.GetBar(barId);
BarDataService.Detach(bar);
foo.Bars.Add(bar);
// Similar code for Request 3
var foo = SessionStore.Get<Foo>("Foo");
FooDataService.Add(foo); // Works
这工作,除。
我在这里做错了什么?
答
在将foo
添加到上下文之前,您必须附加相关的Bar
和Baz
对象。这使实体进入状态Unchanged
和EF只会制造和相关的实体,而不是在数据库中创建新Bar
和Baz
对象foo
之间的关系:
foreach (var bar in foo.Bars)
context.Bars.Attach(bar);
context.Bazs.Attach(foo.Baz);
context.Foos.Add(foo);
context.SaveChanges();