问题
我正在使用Entity Framework将复杂的对象模型添加到数据库中。我遇到一个问题,我尝试插入一个子对象,EF也试图插入父对象,这导致数据库中出现完整性问题。
解释
对于我的例子,我们假设我们有两个表:
商店可以有许多ShopPerformance条目,ShopPerformance必须有商店,商店记录已经存在于数据库中(所以EF应该不管它并专注于ShopPerformance)。
在我的示例中,我只尝试添加ShopPerformance(在这种情况下,ShopPerformance的实例称为“性能”:
this.db.Entry(performance).State = System.Data.EntityState.Added;
this.db.SaveChanges();
当我调用SaveChanges()时,EF也试图插入Shop,这会导致数据库出现约束错误,因为它有约束来防止重复输入(基于商店的名称)。
我尝试过的事情
我已经尝试将ShopPerformance中的Shop属性设置为null以阻止EF执行我不想做的事情(它仍然将ShopID作为单独的属性)。首先我试过了:
Shop theShop = performance.Shop;
performance.Shop = null;
this.db.Entry(performance).State = System.Data.EntityState.Added;
this.db.SaveChanges();
performance.Shop = theShop;
在这种情况下,EF以某种方式重新建立商店和表演之间的联系,并尝试再次插入商店。
然后我尝试了:
Shop theShop = performance.Shop;
this.db.Entry(performance).Entity.Shop = null;
this.db.Entry(performance).State = System.Data.EntityState.Added;
this.db.SaveChanges();
this.db.Entry(performance).Entity.Shop = theShop;
这会导致空引用异常。
所需的解决方案
我正在寻找一种方法来插入我的表演对象而不用EF摆弄商店。这完全打破了我的工作。
TL; DR
我希望实体框架只插入/更新我告诉它的对象,而不是任何相关对象。我怎么能这样做?
答案 0 :(得分:5)
您正在使用断开连接的对象,performance
和performance.Shop
都是EF未跟踪的实体,EF不知道performance.Shop
的状态是什么。
在使用现有performance
添加新的performance.Shop
时,EF不知道performance.Shop
是现有实体,EF会将图表中所有未跟踪的对象标记为Added
也是。
它发生的原因是当你使用DbSet.Add方法时(那个 是,Screencasts.Add),不仅标记了根实体的状态 “已添加”,但图中的所有内容都没有 以前意识到标记已添加。 - MSDN
你需要做的是。
如果您有外键关联,则可以只指定id而不是引用。
performance.ShopId = performance.Shop.Id;
performance.Shop = null;
this.db.Entry(performance).State = System.Data.EntityState.Added;
this.db.SaveChanges();
或者您需要让EF知道performance.Shop
是现有实体,首先将(status = Unchanged
)附加到上下文中。
this.db.Entry(performance.Shop).State = EntityState.Unchanged;
this.db.Entry(performance).State = EntityState.Added;
this.db.SaveChanges();
答案 1 :(得分:1)
你有没有尝试过:
var shop = this.db.shops.Find(id);
shop.Performances.Add(new Performance());
this.db.SaveChanges();
或者
this.db.performances.Add(new Performance() { ShopId = id });
this.db.SaveChanges();