将重复的现有实体附加到新实体

时间:2014-06-13 20:39:35

标签: entity-framework-5

我有一个项目表,其中有三个与联系人表的关联,每个联系人类型一个(赞助商,经纪人,后勤)。我允许用户从现有的联系人列表中进行选择。如果为这些中的两个或多个选择了相同的联系人,我的代码会正确地指向现有条目,但我在数据库中获得了一个新的未使用的联系人条目。

我只允许修改任何重复项中的第一个,我将它们分离,然后在保存之前附加到DbContext。

if (newProject.SponsorContact != null && newProject.SponsorContact.Id > 0)
    if (AttachContact(newProject.SponsorContact))
    SdContext.Entry(newProject.SponsorContact).State = EntityState.Modified;
    else
    newProject.SponsorContact = _contactDataMapper.GetContactById(newProject.SponsorContact.Id);


if (newProject.BrokerContact != null && newProject.BrokerContact.Id > 0)
    if (AttachContact(newProject.BrokerContact))
    SdContext.Entry(newProject.BrokerContact).State = EntityState.Modified;
    else
    newProject.BrokerContact = _contactDataMapper.GetContactById(newProject.BrokerContact.Id);

if (newProject.LogisticsContact != null && newProject.LogisticsContact.Id > 0)
    if (AttachContact(newProject.LogisticsContact))
    SdContext.Entry(newProject.LogisticsContact).State = EntityState.Modified;
    else
    newProject.LogisticsContact = _contactDataMapper.GetContactById(newProject.LogisticsContact.Id);

AttachContact只跟踪附加的联系人ID,如果已经附加,则返回false,以便我可以从上下文中获取现有联系人。

protected bool AttachContact(Contact contact)
{
    if (!_attachedContacts.Contains(contact.Id))
    {
    _attachedContacts.Add(contact.Id);
    return true;
    }
    return false;
}

因此,如果我选择带有ContactId 17的Jacob Marley两次,我的项目将保存两个条目指向正确修改的Jacob Marley id 17,但我得到一个新的Jacob Marley也保存在联系表中,没有项目指向该条目。在组装过程中认真考虑访问上下文,因此我知道已经附加了现有条目。

1 个答案:

答案 0 :(得分:0)

我是C#MVC和实体框架的新手。这可能是常识,但如果您正在阅读本文,您可能会遇到我上面描述的相同问题。

关键要素是有问题的模型有多个引用相同外表的字段,在组装过程中这些是分离的模型。在我的情况下,我有一个项目表,它有三种不同类型的联系人,用户可以为此选择现有的联系人,这可能意味着所有三个字段使用相同的外国联系人。

因此,Project模型每个都有一个int外键字段和一个虚拟模型。

public Nullable<int> SponsorContactId { get; set; }
public Nullable<int> BrokerContactId { get; set; }
public Nullable<int> LogisticsContactId { get; set; }
public virtual Contact SponsorContact { get; set; }
public virtual Contact BrokerContact { get; set; }
public virtual Contact LogisticsContact { get; set; }

因为我构建了汇编程序以从组织级联到项目级别到联系人,所以我无法将联系人组装为附加的。

有两种方法可以解决。

首先要确保将它们组装为附加,这意味着您从上下文中获取联系模型,而不是创建新的联系模型。

第二个是我走的路线。我只允许用户编辑前端和视图模型中的同一个联系人之一,如果它被修改则跟踪。在组装期间,如果联系人存在,则意味着它具有Id&gt; 0,我只会组装虚拟联系人,如果它也被修改。如果它没有被修改,我只填充了int值。因此,如果赞助商联系人存在但未修改,我设置为SponsorContactId并且没有组装联系赞助商联系人。

如果您有任何疑问,请发表评论。我定期办理登机手续,并会回复你。