我在.NET 4.0中使用Entity Framework。我有一个Subscription
实体,它有许多CFile
个实体。我创建了一个新的CFile
实体,但实际上从未在其上调用AddObject
。稍后我尝试保存与它相关的Subscription
实体,EF尝试保存我从未想过的CFile
实例!
简化代码:
var subscription = new Subscription();
Context.Subscription.AddObject(subscription);
Context.SaveChanges();
var cfile = new CFile() { Subscription = subscription };
if (SomeChecksPass(cfile))
{
Context.CFiles.AddObject(cfile);
}
else
{
// No AddObject!
}
subscription.SomeProperty = "changed";
Context.SaveChanges(); // Saves cfile as well, even if I don't want to!
我明白为什么会发生这种情况,但我如何才能不这样做呢?这会产生一个相当微妙和模糊的错误(真正的代码显然要复杂得多)。我希望它只保存我明确传递给AddObject
的实体。
我也知道一种解决方法:在我不想保存的实体上调用Detach
。但是,这不是一个好的解决方法,因为我必须确保在未保存cfile
的每个可能的代码路径中调用Detach(并且在某些代码路径中保存它),因此必须在之后调用它决定,但在保存之前。这非常脆弱,我真的不想依赖它。
编辑: cfile
已创建,因为我确实想要保存大多数,但如果某些验证失败或发生了某些错误,那么我就不会“T。我仍然希望保存对subscription
对象的一些更改。
答案 0 :(得分:1)
尝试在您的EDMX中公开外键(如果还没有),请执行以下操作: -
var cfile = new CFile() { SubscriptionId = subscription.Id };
这应该足以防止形成对象图。
您可能需要在创建订阅对象后调用Refresh(取决于您的ID的生成方式 - 大多数会在SaveChanges()时自动更新。)
答案 1 :(得分:1)
您不直接控制要在Entity Framework中保存的实体,它会保存它认为应该的内容,它可以与关联的对象图一起使用。您可以使用ObjectStateManager在ObjectContext.SaveChanges覆盖中放置一些逻辑,但这非常难看。
如果您需要更多地控制要保存的内容以及何时保存,可能最好使用其他模式,如Repository | ActiveRecord,您可以更好地控制单独的实体。或者你经常会遇到你所描述的情况。
答案 2 :(得分:1)
使用时遇到了同样的问题:
List<Ey> eys = dc.Context.Ey.ToList();
eys = eys .Where(h => h.Employee == myEmployee).ToList();
Ey esh;
for (int k = 1; k < 5; k++)
{
EmployeeSkillHistory duplicate = histories.Where(h => h.Sl == esh.Sl).FirstOrDefault();
if (duplicate == null)
{ dc.Context.Ey.AddObject(esh); } else { dc.Context.Ey.DeleteObject(esh); }
dc.Context.SaveChanges();
}
使用前
else { dc.Context.Ey.DeleteObject(esh); }
重复项保存在我的数据库中