C# 实体框架多对多更新
我正试图找到更新多对多关系的合适形式,但我发现了一些问题 该应用程序是一个带有简单注入器的asp.net mvc(根据上下文设置) 我有一个实体人有一个IEnumerable,我还有一个实体团队有一个IEnumerable 人员实体有一些其他字段,如描述、电子邮件等,在其视图中,有一些复选框,用户可以选择团队 我曾试图在网上搜索更新多对多关系的最佳方法,但我只找到了删除第三个表中创建的所有内容,然后再次添加团队 下面是我试图做的,但我得到的pk已经存在。我知道这是因为首先我用Find方法加载People实体(删除foreach中的团队列表),然后尝试附加(当错误发生时)修改的对象以将其状态设置为modifiedC# 实体框架多对多更新,c#,asp.net,entity-framework,C#,Asp.net,Entity Framework,我正试图找到更新多对多关系的合适形式,但我发现了一些问题 该应用程序是一个带有简单注入器的asp.net mvc(根据上下文设置) 我有一个实体人有一个IEnumerable,我还有一个实体团队有一个IEnumerable 人员实体有一些其他字段,如描述、电子邮件等,在其视图中,有一些复选框,用户可以选择团队 我曾试图在网上搜索更新多对多关系的最佳方法,但我只找到了删除第三个表中创建的所有内容,然后再次添加团队 下面是我试图做的,但我得到的pk已经存在。我知道这是因为首先我用Find方法加载Pe
public override void Modify(People obj)
{
var ppl = SearchById(obj.Id);
if (ppl.Teams.Count > 0)
{
foreach (var team in ppl.Teams.ToList())
{
ppl.Teams.Remove(team);
}
}
var entry = lpcContext.Entry(obj);
if (lpcContext.Entry(obj).State == EntityState.Detached)
dbSet.Attach(obj);
entry.State = EntityState.Modified;
}
为了解决一些问题,我使用了工作单元模式,所以我会在以后保存更改
是否有其他方法,或者我必须逐个删除团队,保存更改,然后再次更新对象并保存更改?不幸的是,在EF中使用分离的实体并不是那么简单(目前)。EF中的Attach()仅适用于连接的实体。这意味着,如果从DB加载对象,则将其传递到视图(或者页面是asp.net)。当您从该视图/页面读回该对象时,EF将不再跟踪该对象。如果现在尝试使用Attach(),则会出现一个错误,即该键已存在于DBContext中。要解决此问题,需要找到条目并使用SetValues()对实体进行更改。大概是这样的:
public virtual void Update(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
var pkey = _dbset.Create().GetType().GetProperty("Id").GetValue(entity);//assuming Id is the key column
var set = DbContext.Set<T>();
T attachedEntity = set.Find(pkey);
if (attachedEntity != null)
{
var attachedEntry = DbContext.Entry(attachedEntity);
attachedEntry.CurrentValues.SetValues(entity);
}
}
}
公共虚拟无效更新(T实体)
{
DbEntityEntry DbEntityEntry=DbContext.Entry(实体);
if(dbEntityEntry.State==EntityState.Distached)
{
var pkey=_dbset.Create().GetType().GetProperty(“Id”).GetValue(entity);//假设Id是键列
var set=DbContext.set();
T attachedEntity=set.Find(pkey);
如果(附件身份!=null)
{
var attachedEntry=DbContext.Entry(attachedEntity);
attachedEntry.CurrentValues.SetValues(实体);
}
}
}
请注意,这将忽略任何嵌套对象。因此,您应该执行DB trip,并比较从DB返回的对象,以确定是否应该对每个子对象调用Add、Update或Delete。这是我在EF中处理断开连接的对象时能找到的最佳解决方法。我想nHibernate没有这个bug。上次我读到这篇文章时,微软打算在EF6.x之后再做这方面的工作。所以,我想我们得等着。请通读以下文章,以详细了解问题(以及可能的解决方案):
要讨论您的特定场景,您应该点击DB,查看是否选择了任何新团队或删除了某些现有团队,并通过比较DB返回的人员对象的团队集合与从视图/页面返回的人员对象来调用add或delete(视情况而定)。要更新People对象本身,可以使用上面给出的update()。是否加载了相同的上下文?@Rob是的Rob,我忘了说,我正在使用MVC和Simple Injector(每个请求的上下文)。我将编辑问题这是一个很好的解决方法,我必须尝试一下,因为我找不到关于这个问题的任何其他信息。谢谢你!