我怎么能有实体框架工作与我的分离对象图
本文关键字:我的 分离 对象图 工作 框架 怎么能 实体 | 更新日期: 2023-09-27 18:01:42
在我的应用程序中,我们为每个HTTP请求获得DbContext
的新实例。在正常的工作流程中,我们创建一个实体并开始填充它的导航属性:
// 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!
Add通常只是将实体添加到DbSet
,然后调用save changes:
Set.Add(entity);
Context.SaveChanges();
显然,由于foo
对象包含多个代理对象,每个代理对象都附加到不同的DbContexts
,因此失败。我们决定的解决方案是分离接收到的对象:
// 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
可以工作,除了,因为这现在创建了Bar
和Baz
对象的新实例。
我在这里做错了什么?
在将foo
添加到上下文中之前,必须附加相关的Bar
和Baz
对象。这将实体置于状态Unchanged
, EF将只创建foo
和相关实体之间的关系,而不是在数据库中创建新的Bar
和Baz
对象:
foreach (var bar in foo.Bars)
context.Bars.Attach(bar);
context.Bazs.Attach(foo.Baz);
context.Foos.Add(foo);
context.SaveChanges();