我有一个父实体
存在于db中的 foo
,我在此实体上有一个属性bar
(一对多关系)。
Foo
已分离,因为它使用WebApi进行反序列化,所以我这样做foo
context.Foos.AddOrUpdate(foo);
即使附加了一个新的bar
引用,它也不会被保存,但是对于我们拥有的多对多关系的另一个关系它确实如此。如果我向该集合添加一个新实体,它将被保存到它的表中,并且还会在关系表中添加一行。
如果我在调用context.Bars.AddOrUpdate(foo.Bar);
之前context.Foos.AddOrUpdate(foo);
,它会将新栏正确保存到条形表,但它不会将正确的barId添加到foo表
@Yuliam Chandra
如果我理解你的答案是正确的(我认为你在答案中混淆了酒吧和泡沫)这应该有用吗?
var foo = new Foo();
foo.FooId = 524 //Existing foo;
foo.Bar = new Bar(); //Completely new bar
db.Foos.AddOrUpdate(foo);
db.SaveChanges();
但它没有
答案 0 :(得分:2)
使用断开连接的对象需要额外的代码。
如果您使用断开连接的对象,则必须手动管理 同步。
如果Bar
是现有实体,则需要先将其附加,因此Foo
将添加为Bar's
个孩子。
if (foo.Bar.Id != 0)
{
context.Bars.Attach(foo.Bar);
context.Foos.AddOrUpdate(foo);
}
上述代码的示例与this article中的Course
(Foo
)和Department
(Bar
)示例类似。
但如果Bar
是新实体,您只需添加Foo
,那么{I}也会被添加。
Bar
可以在my answer上查看其他一些品种。
在进一步解释之前,我想展示相同的代码。
else
{
context.Foos.Add(foo);
}
等于db.Set<T>().Add(instance)
db.Entry(instance).State = EntityState.Added;
等于db.Set<T>().Attach(instance)
之前的回答解释了两个条件。
New Foo和现有的Bar
db.Entry(instance).State = EntityState.Unchanged;
context.Bars.Attach(foo.Bar);
New Foo和New Bar
context.Foos.AddOrUpdate(foo);
context.Foos.Add(foo);
, Added
就会有特殊情况。即使任何引用实体是数据库中的现有对象,图中的所有实体也将被标记为Added
。如果我们有这个代码,将添加Foo和Bar。
Added
为了防止这种情况发生,需要首先附加Bar。
var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Foo>().Add(foo);
db.SaveChanges();
检查Julie Lerman article以获得更完整的解释。
它发生的原因是当你使用DbSet.Add方法时(那个 是,Screencasts.Add),不仅标记了根实体的状态 “已添加”,但图中的所有内容都没有 以前意识到标记已添加。即使是开发人员 可能知道主题具有现有的Id值,实体框架 尊重其EntityState(已添加)并创建一个Insert数据库命令 对于主题,无论现有的Id。
您最新的问题是关于现有的Foo和新酒吧。使用您的代码,结果将不会添加新的Bar,现有的Foo也不会与新的Bar建立关系。
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();
如果我们手动将条形码与var foo = new Foo();
foo.FooId = 524 //Existing foo;
foo.Bar = new Bar(); //Completely new bar
db.Foos.AddOrUpdate(foo);
db.SaveChanges();
一起添加,结果仍然不符合预期。新栏将被添加,但Foo将与新栏没有关系。
AddOrUpdate(foo)
db.Bars.Add(foo.Bar);
db.Foos.AddOrUpdate(foo);
的行为不一致。
如果您使用断开连接的对象,则必须手动管理 同步。
此代码应适用于所有条件。
此代码取决于id(id = 0是一个新实体)。
AddOrUpdate
与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();
相关,我认为可以找到一个未解决的问题here。