使用断开连接的对象需要额外的代码。
如果您正在使用断开连接的对象,则必须手动管理
同步。
Source http://msdn.microsoft.com/en-us/library/ee373856.aspx
If Bar
是一个现有实体,您需要先附加它,所以Foo
将被添加为Bar's
孩子们。
if (foo.Bar.Id != 0)
{
context.Bars.Attach(foo.Bar);
context.Foos.AddOrUpdate(foo);
}
上面代码的例子类似Course
(Foo
) and Department
(Bar
) 中的示例本文 http://msdn.microsoft.com/en-us/data/jj713564.aspx.
But if Bar
是一个您只需添加的新实体Foo
, then Bar
也将被添加。
else
{
context.Foos.Add(foo);
}
其他一些品种可以检查我的答案 https://stackoverflow.com/a/24886346/968303.
update
在进一步解释之前,我想展示相同的代码。
-
db.Set<T>().Add(instance)
等于db.Entry(instance).State = EntityState.Added;
-
db.Set<T>().Attach(instance)
等于db.Entry(instance).State = EntityState.Unchanged;
前面的答案解释了两个条件。
特别添加
Added
有特殊条件,一旦实体被标记为Added
。图中的所有实体将被标记为Added
即使任何引用实体是数据库中的现有对象也是如此。如果我们有这段代码,Foo 和 Bar 将被添加。
var foo = new Foo (); // new foo
foo.Bar = new Bar { BarId = 123 }; // existing bar
db.Set<Foo>().Add(foo);
db.SaveChanges();
为了防止这种情况发生,需要先附加 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();
Check 朱莉·勒曼文章 http://msdn.microsoft.com/en-us/magazine/dn166926.aspx以获得更完整的解释。
发生这种情况的原因是当您使用 DbSet.Add 方法时(即
即Screencasts.Add),不仅标记了根实体的状态
“已添加”,但图中的所有内容都不是上下文
之前意识到的也被标记为已添加。尽管开发商
可能知道Topic有一个现有的Id值,Entity Framework
遵循其 EntityState(已添加)并创建插入数据库命令
对于主题,无论现有的 Id 是什么。
根据您的更新调整说明
您更新的问题是关于现有的 Foo 和新的 Bar。使用您的代码,结果将不会添加新的 Bar,并且现有的 Foo 将不会与新的 Bar 建立关系。
var foo = new Foo();
foo.FooId = 524 //Existing foo;
foo.Bar = new Bar(); //Completely new bar
db.Foos.AddOrUpdate(foo);
db.SaveChanges();
如果我们手动将 Bar 添加到AddOrUpdate(foo)
,结果还是没有达到预期。将添加新的 Bar,但 Foo 将与新的 Bar 没有关系。
db.Bars.Add(foo.Bar);
db.Foos.AddOrUpdate(foo);
的行为AddOrUpdate
不一致。
Solution
如果您正在使用断开连接的对象,则必须手动管理
同步。
该代码应该在所有条件下都有效。
- 新Foo和新酒吧
- 新Foo和现有酒吧
- 现有的 Foo 和新的 Bar
- 现有的 Foo 和现有的 Bar
此代码取决于 id(id = 0 是一个新实体)。
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
,我认为有一个未解决的问题可以找到here https://entityframework.codeplex.com/workitem/2128.