繁体   English   中英

新子项在Entity Framework 4中插入现有父项

[英]New child inserts existing parent in Entity Framework 4

当我尝试向现有父对象添加新的子关系时, 实体尝试将父对象插入为对象,而不是将其更新为已修改 我收到一个错误,说它试图插入一个重复的密钥

这真的让我感到困惑,直到我用一个新关系更新模型(通过数据库更新,而不是代码优先),它才表现得像这样。 在相同上下文中具有相同多对多模式的其他表不会导致此错误!

我发现如果我将我的子对象添加到上下文中,仔细设置ID值,而不是导航属性,它将保存正常。 但是修复过程不是将子对象添加到导航集合中 ,这会导致其他地方出现逻辑问题。

我的模型有很多这样的关系:

选项 - <optionUnit> - 单位

Option和Unit对象都存在加载到上下文中。

通常我会创建桥表并设置如下导航属性:

bridge = new OptionUnit()
{
    OptionUnitId = Guid.NewGuid(),
    Unit = SelectedUnit,
    Option = SelectedOption,
};
//Context.OptionUnits.Add(bridge); //added to context via the navigation properties

但是当我这么做的时候,实体试图将SelectedOption插入为新的(即使它的实体状态在保存时被修改,而不是新的或分离的)。

为了解决这个问题,我不得不建立桥梁并设置id。 我在保存时没有收到任何错误,但它不会像我期望的那样通过修复自动添加到SelectedOption.OptionUnits。 如果我手动将其添加到集合中,我再次收到保存错误。

bridge = new OptionUnit()
{
    OptionUnitId = Guid.NewGuid(),
    //Unit = SelectedUnit,
    UnitId = SelectedUnit.UnitId,
    //Option = SelectedOption,
    OptionId = SelectedOption.OptionId,
};
Context.OptionUnits.Add(bridge);

这似乎只发生在选项实体的关系上。 另外一个关系,在optionUnit> - Unit之间没有任何问题,并按预期工作。

对于这种关系来说,这似乎有些不对,但我不确定在哪里看。 我需要知道导致这种行为的原因,如何修复它,以及如何防止它在将来发生....

令人难以置信的是,Julie Lerman刚刚收到了一篇关于这个确切问题及其发生原因的MSDN文章。 你可以在这里找到这篇文章。

用朱莉自己的话说:

它发生的原因是,当您使用DbSet.Add方法时,不仅将根实体的状态标记为“已添加”,而且上下文之前未知的图中的所有内容都标记为已添加。 即使开发人员可能知道该对象具有现有Id值,Entity Framework也会尊重其EntityState(已添加)并为该对象创建Insert数据库命令,而不管现有Id是什么。

那么这里简单地说,当你说Context.OptionUnits.Add(bridge); ,它也认为你也试图将Option和Unit对象添加到它。 相反,你需要使用FK(如她提到的那样),然后添加它。

我认为这就是你在第二次尝试时要做的事情,但我想知道你是如何检查它是否在SelectedOption.OptionUnits 保存后是否正在尝试检查? 在这种情况下,它不会显示,因为当Entity Framework提取该值时,该值会缓存在内存中。 之后你需要尝试再次提出该对象。

我发现了这个问题。 添加子项后,我会运行一些逻辑来更新一些总计。 问题是我使用了RaiseDataMemberChanged(“sum”)而不是RaisePropertyChanged(“sum”)。 RaiseDataMemberChanged()必须将实体中的某些内容标记为已修改,并且正在解决此问题。 感谢IronMan84的所有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM