新的子实体将不保存在父实体被保存 [英] New subentity will not save when parent entity is saved

查看:200
本文介绍了新的子实体将不保存在父实体被保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父实体

中存在的分贝,我有一个属性本实体(一对多关系)。

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 to db.Entry(instance).State = EntityState.Added;
  • db.Set<T>().Attach(instance) equals to db.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆