我如何让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。我们决定在是分离的对象,我们是接受的解决方案:对于事实,这现在创建BarBaz对象的新实例

// 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添加到上下文之前,您必须附加相关的BarBaz对象。这使实体进入状态Unchanged和EF只会制造和相关的实体,而不是在数据库中创建新BarBaz对象foo之间的关系:

foreach (var bar in foo.Bars) 
    context.Bars.Attach(bar); 
context.Bazs.Attach(foo.Baz); 
context.Foos.Add(foo); 
context.SaveChanges();