实体框架4.3.1的DbContext添加对象与现有引用的对象
(首先抱歉的英语不好)实体框架4.3.1的DbContext添加对象与现有引用的对象
我是新来的实体框架和我做测试的一点点。让我们假设我有2个对象是POCO对象。人员和地址。
我的场景是,我想添加一个新的人到DbContext有一个已经存在的对象的引用。两个实体之间的连接是一个Many:Many关系。
using (var t = new Tww.SV.Models.Model.Portal.SVPortalEntities())
{
testaddress = (from c in t.Adresses
select c).ToList().FirstOrDefault();
}
var newPerson = new Person();
newPerson.Name = "Henry";
newPerson.Adresses.Add(testaddress);
using (var k = new Tww.SV.Models.Model.Portal.SVPortalEntities())
{
k.Persons.Add(newPerson);
k.SaveChanges();
}
我现在做的问题是,一旦人是增加了一个额外的地址(具有相同的价值观,但一个新的密钥)将被创建。我如何将现有的引用添加到新的对象而不是创建一个新的对象?
整个操作使用一个上下文:
using (var t = new Tww.SV.Models.Model.Portal.SVPortalEntities())
{
testaddress = (from c in t.Adresses
select c).ToList().FirstOrDefault();
var newPerson = new Person();
newPerson.Name = "Henry";
newPerson.Adresses.Add(testaddress);
k.Persons.Add(newPerson);
k.SaveChanges();
}
如果你不能做那么,您需要通过ObjectStateManager或类似的方法手动更改新上下文中现有地址的状态。
迭代最后我使用了这些自我追踪对象 – KroaX 2012-03-16 13:19:36
首先,您是否需要在数据上下文的两个单独实例中执行此操作?我假设你这样做,并且你只是提供了一个简化的例子,但是如果没有,那么在整个代码中使用相同的上下文实例将解决你的问题。
但是,这是一个常见问题,特别是在跨WCF等服务使用EF类时。我发现的最佳解决方案是在保存传入的新对象之前“修复”新传入的对象。我会成为第一个管理员,我觉得这个“丑陋”,但我也没有找到任何更好的选项,实际上一直工作。我通常把参考重新关联的代码放到一个方法,在我的实体类的另一部分类段:
public void FixUp(EntityContext c)
{
for (int i = 0; i < this.Addresses.Count; i++)
{
var existing = c.Addresses.SingleOrDefault(a => a.Id = this.Addresses[i].Id);
if (existing != null)
{
this.Addresses[i] = existing;
}
}
}
using (var k = new EntityContext())
{
newPerson.FixUp(k);
k.Persons.Add(newPerson);
k.SaveChanges();
}
解释为什么会发生这种情况:您正在创建两个DbContext。首先,您检索一个地址对象。然后,在任何Context范围之外(请参阅使用),您正在创建一个新的脱节人。它不属于你的两种情况之一。接下来发生的事情是,您创建一个新的上下文并添加您的对象到其中。
此背景下,现在不知道你的新人(这是“超出范围”,或独立),也不是你的ADRESS(这是从另一个方面)。这两个实体都将被添加并标记为ChangeTracker,已添加。
你有多个解决方案:
首先,只能使用一个上下文检索您ADRESS,在创建人和添加它。你需要稍微改变一下你的代码,如果你正在开发基于服务的场景,它可能不适合你。
第二,如果你有没有改变这个代码的机会,你需要连接分离对象,就像你在你的代码片段做,你可能希望覆盖的SaveChanges你的上下文类,并通过实体迭代在ChangeTracker。那些已保存的(Id> 0)可能会设置为“未更改”,或者如果您想保留最终进行的更改,请使用“修改”。这感觉很难看,但它应该工作。
最简单的办法是重写的SaveChanges,通过已保存的所有实体和那些(ID> 0),将其设置为“不变”,或者,如果你想坚持最终取得了修改,“修改时间” – UrbanEsc 2012-03-14 17:36:48