使用多对多映射更新分离的EF对象

时间:2014-02-20 11:50:36

标签: c# entity-framework repository

我在EF中有一个存储库,需要更新分离的实体,但存在于ObjectStateManager中的实体。假设您在已加载特定实体的DBContext上打开了会话,但随后您收到了从该对象的分离版本更新的请求。我发现这样做的唯一方法是获取状态管理器中的现有对象,然后逐个更新字段到传入对象的字段。然后将对象状态管理器版本的状态设置为modified,并保存上下文。

这适用于不包含导航属性的简单实体。

我现在正试图在具有多对多关系的实体上这样做。

想象一下,你有一个BlogPost对象和一个Hashtag对象。这是一对多关系。我已经定义了这个,在数据库中我可以看到我有三个表,BlogPost,HashTag和映射表。

我希望能够做的是编辑前端的博客文章,传递更新的博客文章,其中包含适用于它的新标签列表,并更新数据库。

问题是主题标签列表可能与旧标签完全无关,所以我首先必须清除所有以前的映射,然后添加新的映射。如果它们是相同的,这将是必要的冗余但实现它的唯一途径。

我无法弄清楚如何在多对多的关系中清除以前的映射。我试过了

foreach (var tag in dbBlogPost.Hashtags)
    dbItem.Hashtags.Remove(tag);

然后我将新的主题标签添加到空集合中,然后执行

Work.Context.Entry(dbItem).State = EntityState.Modified;
Work.Context.Save();

但是当我保存存储库时,我得到以下异常

  

操作失败:无法更改关系,因为   一个或多个外键属性是不可为空的。当一个   改变了关系,相关的外键属性是   设置为空值。如果外键不支持空值,   必须定义新的关系,外键属性必须是   分配了另一个非空值,或者不相关的对象必须是   删除。

任何人都可以建议我做错了吗?

1 个答案:

答案 0 :(得分:0)

DbSet<TEntity>.Local表示此集合中所有已添加,未更改和已修改实体的本地视图。因此,您可以在进行任何更改之前清除所有集合。

dbBlogPost.Hashtags.Local.Clear();