【问题标题】:Entity framework many to many keeps adding extra record多对多的实体框架不断添加额外的记录
【发布时间】:2011-04-11 15:20:12
【问题描述】:

我正在尝试首先使用实体​​框架代码将新记录添加到链接表中。我在UserRole 上拥有的是多对多。我的情况是,当我为用户更改角色时,我删除了他们以前的所有角色并添加新角色,如下所示:

//Delete all associated roles for user
var roleUser = db.Users.Include(r => r.Roles).FirstOrDefault(u => u.UserId == user.UserId);
var usersRoles = roleUser.Roles;

usersRoles.ForEach(role => roleUser.Roles.Remove(role));

//add the new roles
roleUser.Roles.AddRange(detachedUser.Roles);

db.SaveChanges();

所以它可以完美地删除它们。但是在添加新角色时,它不仅将其添加到链接表中,还会将其添加到Role 表中。一个全新的角色会在没有RoleName 的情况下添加。 user.Roles 将包含具有以下数据的项目:

RoleId;//1 <-- this Id exists in the database already but yet still it creates one instead of a linktable record.
RoleName;//null

如何防止 EF 添加一条全新的记录而只是将一条记录添加到链接表中?

更新:我最终这样做了:

var roleUser = db.Users.Include(r => r.Roles).FirstOrDefault(u => u.UserId == user.UserId);
var roles = db.Roles;

foreach (var role in roles)
{
     if (user.Roles.Any(r => r.RoleId == role.RoleId))
     {
          roleUser.Roles.Add(role);
     }
     else
     {
         roleUser.Roles.Remove(role);
     }
}
db.SaveChanges();

【问题讨论】:

  • 显然已解决,但无法了解已解决的问题。您能否再次发布答案中阻止创建新角色的部分。

标签: entity-framework ef-code-first


【解决方案1】:

在向用户添加新角色之前尝试保存

//Delete all associated roles for user 
var roleUser = db.Users.Include(r => r.Roles).FirstOrDefault(u => u.UserId == user.UserId); 
var usersRoles = roleUser.Roles; 

usersRoles.ForEach(role => roleUser.Roles.Remove(role));  
db.SaveChanges(); 

roleUser.Roles.AddRange(user.Roles); //add the new roles 
db.SaveChanges(); 

编辑:

看看这个:

roleUser.Roles.AddRange(user.Roles); //add the new roles 

user.Roles 来自哪里?

【讨论】:

  • 添加第二个 SaveChanges 后我仍然遇到同样的问题。
  • 我认为这是我添加新角色的方式。我可能必须从数据库中获取所有这些并添加它们
  • 当您遇到此类问题时,您可能还想查看您的绑定配置。我过去曾遇到过类似的问题。
  • 从数据库中取回它们有什么改变吗?
  • @lol 编码器,您找到了创建角色的原因。这些实体被视为新实体。很高兴看到你解决了它:)
【解决方案2】:

我认为您遇到的问题是您需要在将角色添加到用户之前附加角色。

您也不需要全部删除,只需删除已删除的,然后只添加新的即可。

【讨论】:

  • 我同意@moi_meme 关于您只需要删除需要删除的部分的观点。另一方面,我不认为这是一个触及附加/分离状态的问题。因为对象永远不会分离。
  • @Alexandre Brisebois - 我写道,因为他的变量被称为 DetachedUser
  • 糟糕的是我没有注意到那部分
【解决方案3】:

对于您添加的每个卷,您可以尝试检查或设置实体状态。例如,在这里我将集合设置为 unaged。这样它就不会尝试插入或更新它。

myContext.Entry(roll).State = EntityState.Unchanged

更多信息在这里: http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx

【讨论】:

  • 是的,但如果他在尝试添加新角色之前保存,实体的状态不会改变(保存后)
猜你喜欢
  • 2013-06-30
  • 1970-01-01
  • 2021-10-16
  • 2013-06-27
  • 1970-01-01
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多