当我从未将实体添加到上下文时,实体框架错误地保存了实体

时间:2010-12-16 04:45:23

标签: .net entity-framework orm

我在.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对象的一些更改。

3 个答案:

答案 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); }

重复项保存在我的数据库中

相关问题