新的子实体将不保存在父实体被保存 [英] New subentity will not save when parent entity is saved
问题描述
我有一个父实体
富
中存在的分贝,我有一个属性栏
本实体(一对多关系)。
foo
which exists in the db, I have a property bar
on this entity (One to many relation).
富
被分离,因为它使用的WebAPI反序列化,所以我这样做是为了富
Foo
is detached because its deserialized using WebApi, so I do this to foo
context.Foos.AddOrUpdate(foo);
即使有一个新的栏
参考连接到它,它不会得到保存,但它确实是这样工作的另一个关系,我们有这是一个多对多的关系。如果我添加一个新的实体,该集合将被保存到它的表,也有一行被添加到关系表。
Even If there is a new bar
reference attached to it, it wont get saved, however it does work like this for another relation we have which is a Many to many relation. If I add a new entity to that collection it will be saved to its table and also a row is added to the relation table.
如果我 context.Bars.AddOrUpdate(foo.Bar);
之前调用 context.Foos.AddOrUpdate(富);
它将正确保存新的酒吧酒吧台,但它不会添加正确的barId到foo表
If I do context.Bars.AddOrUpdate(foo.Bar);
before calling context.Foos.AddOrUpdate(foo);
it will save the new bar correctly to the bar table, but it wont add the correct barId to the foo table
@Yuliam钱德拉
如果我理解正确答案(我想你是酒吧和FOOS混合在你的答案)这应该工作?
If i understand your answer correctly (I think you are mixing up bars and foos in your answer) this should work?
var foo = new Foo();
foo.FooId = 524 //Existing foo;
foo.Bar = new Bar(); //Completely new bar
db.Foos.AddOrUpdate(foo);
db.SaveChanges();
但事实并非如此。
But it does not
推荐答案
与断开连接的对象来处理,需要额外的代码。
Working with disconnected objects needs extra code.
如果您正在使用您必须手动管理$断开连接的对象工作b $ b中的同步。
If you are working with disconnected objects you must manually manage the synchronization.
的来源
如果酒吧
是现有实体您首先要重视它,所以富
将被添加为酒吧的
孩子
If Bar
is an existing entity you need to attach it first, so Foo
will be added as Bar's
children.
if (foo.Bar.Id != 0)
{
context.Bars.Attach(foo.Bar);
context.Foos.AddOrUpdate(foo);
}
以上代码的例子是课程类似
(富
)和处
(酒吧
)的例子在这篇文章。
The example of above code is similar with Course
(Foo
) and Department
(Bar
) example in this article.
但是,如果酒吧
是你只需要添加富
,然后一个新的实体酒吧
也将增加。
But if Bar
is a new entity you just need to add Foo
, then Bar
will also be added.
else
{
context.Foos.Add(foo);
}
其他的一些品种上可以的my~~MD~~aux回答。
在。进一步的解释,我想显示了相同的代码
Before explaining further, I'd like show identical code.
-
db.Set< T>()添加(实例)
等于db.Entry(实例).STATE = EntityState.Added;
-
db.Set< T>()将(实例)
等于db.Entry(实例).STATE = EntityState.Unchanged;
db.Set<T>().Add(instance)
equals todb.Entry(instance).State = EntityState.Added;
db.Set<T>().Attach(instance)
equals todb.Entry(instance).State = EntityState.Unchanged;
以前的答案解释了约两个条件。
The previous answer explained about two conditions.
-
新富和现有的酒吧
New Foo and existing Bar
context.Bars.Attach(foo.Bar);
context.Foos.AddOrUpdate(富);
新富和新酒吧
context.Foos.Add(富);
添加
有特殊的情况下,一旦一个实体被标记为添加
。图中的所有实体将被标记为添加
过,即使任何参考实体是在数据库中的现有对象。如果我们有这样的代码,Foo和酒吧将被添加
Added
has special condition, once an entity is marked as Added
. all the entities in the graph will be marked as Added
too, even if any reference entity is an existing object in the database. If we have this code, Foo and Bar will be added.
var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Foo>().Add(foo);
db.SaveChanges();
要防止这种情况发生,酒吧需要先装。
To prevent that from happening, Bar needs to be attached first.
var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Bar>().Attach(bar);
db.Set<Foo>().Add(foo);
db.SaveChanges();
检查的朱莉·勒曼文章更完整的解释。
它发生的原因是当您使用DbSet.Add法(即
是Screencasts.Add),不仅是根实体的标记
增加,但一切都在图中的背景是不是国家
以前知道被标记加入。尽管开发商
可能知道的主题有一个现有ID,和实体框架
信守EntityState(新增),并为主题创建一个插入数据库命令
,无论原有的同上。
The reason it happens is that when you use the DbSet.Add method (that is, Screencasts.Add), not only is the state of the root entity marked "Added," but everything in the graph that the context was not previously aware of is marked Added as well. Even though the developer may be aware that the Topic has an existing Id value, Entity Framework honors its EntityState (Added) and creates an Insert database command for the Topic, regardless of the existing Id.
和更新后的问题大约是现有Foo和新的酒吧。用你的代码,结果将不会增加新的酒吧和现有美孚不会作出新的酒吧有关系。
Adjust Explanation Based On Your Update
And your updated question is about existing Foo and new Bar. Using your code, the result will not add new Bar and existing Foo will not make a relationship with new Bar.
var foo = new Foo();
foo.FooId = 524 //Existing foo;
foo.Bar = new Bar(); //Completely new bar
db.Foos.AddOrUpdate(foo);
db.SaveChanges();
如果我们手动 AddOrUpdate(富)一起加入吧
,结果仍不如预期。新的酒吧将被添加,但富不会有新酒吧的关系。
If we manually add the Bar together with AddOrUpdate(foo)
, the result is still not as expected. The new Bar will be added, but Foo will not have relationship with the new Bar.
db.Bars.Add(foo.Bar);
db.Foos.AddOrUpdate(foo);
的 AddOrUpdate
的行为是不一致的。
如果您正在使用断开连接的对象,你必须手动管理$ b工作$ b同步。
If you are working with disconnected objects you must manually manage the synchronization.
这代码应该在所有的条件下工作。
This code should work in all conditions.
- 新富和新酒吧
- 新Foo和现有的酒吧
- 现有Foo和新酒吧
- 现有Foo和现有的酒吧
- New Foo and New Bar
- New Foo and Existing Bar
- Existing Foo and New Bar
- Existing Foo and Existing Bar
此代码依赖于标识(ID = 0是一个新的实体)。
This code depends on the id (id = 0 is a new entity).
db.Entry(foo).State =
foo.FooId == 0 ? EntityState.Added : EntityState.Modified;
if (foo.Bar != null)
{
db.Entry(foo.Bar).State =
foo.Bar.BarId == 0 ? EntityState.Added : EntityState.Modified;
^^^
// If you don't want to change the Bar while creating a relationship between
// Foo and with existing Bar, you can change
// `EntityState.Modified` with `EntityState.Unchanged`
}
db.SaveChanges();
相关 AddOrUpdate
,我觉得这是一个开放的问题,可以发现这里。
Related to AddOrUpdate
, I think there is an open issue that can be found here.
这篇关于新的子实体将不保存在父实体被保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!