【问题标题】:Copying a collection of entites复制实体集合
【发布时间】:2012-09-20 15:49:47
【问题描述】:

我正在尝试使用以下方法将用户角色列表从一个用户复制到另一个用户:

public bool CopyUsersRoles(Guid copyFromUserId, Guid copyToUserId)
{
    //Delete existing roles for user
    var rolesToDelete = context.UserApplicationRoles.Where(x => x.UserID == copyToUserId);

    foreach (var u in rolesToDelete)
    {
        context.UserApplicationRoles.DeleteObject(u);
    }    

    var rolesToAdd = context.UserApplicationRoles.Where(x => x.UserID == copyFromUserId)
                                  .ToList();                             

    for(int i = 0; i < rolesToAdd.Count; i++)
    {
        rolesToAdd[i].UserID = copyToUserId;                           
    }    

    foreach (var u in rolesToAdd)
    {
        context.UserApplicationRoles.AddObject(u);
    }    

    context.SaveChanges();    
}

分配新的UserId 时出现以下异常:

“UserID”属性是对象的关键信息的一部分,不能修改。 在 System.Data.Objects.EntityEntry.VerifyEntityValueIsEditable(StateManagerTypeMetadata typeMetadata, Int32 ordinal, String memberName)

我原以为 ToList() 会阻止这种情况...

实现这一目标的正确方法是什么?

编辑 - 课程详情:

我看到旧表上没有设置 PK。我假设手动将 PK 设置为 UserApplicationRoleId 将解决此问题。

UserId 看起来像这样:

    [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.Guid UserID
    {
        get
        {
            return _UserID;
        }
        set
        {
            if (_UserID != value)
            {
                OnUserIDChanging(value);
                ReportPropertyChanging("UserID");
                _UserID = StructuralObject.SetValidValue(value);
                ReportPropertyChanged("UserID");
                OnUserIDChanged();
            }
        }
    }

【问题讨论】:

  • 您需要将角色添加到用户角色集合中,而不是更改用户ID!!!
  • 我需要使用现有角色,使用新用户 ID 创建它们的副本,然后将具有新 ID 的角色添加到集合中。我可能在这里遗漏了一些非常明显的东西!
  • 你能发布Role类吗?
  • 这个类实际上叫做UserApplicationRole...我只是为了例子简化了它。它是一个 EntityObject,所以这个类非常大:我会尝试发布相关位 - 给我几分钟

标签: c# entity-framework


【解决方案1】:

这就是问题所在:

  var rolesToAdd = context.UserApplicationRoles
  .Where(x => x.UserID == copyFromUserId)                             
  .ToList();  

   ....

  foreach (var u in rolesToAdd)
  {
    context.UserApplicationRoles.AddObject(u);
  } 

您正在引用 DB/EF 中已经存在的对象。您必须克隆这些并将克隆添加到 EF。

【讨论】:

    【解决方案2】:

    最终让它以一种非常讨厌的方式工作(旧版数据库没有自动递增的 PK :(

                var copyToUser = this.GetUser(copyToUserId);
                List<UserApplicationRole> userApplicationRoles = new List<UserApplicationRole>();
                int startingId = Convert.ToInt32(isignonContext.UserApplicationRoles.OrderByDescending(u => u.UserApplicationRoleId).FirstOrDefault().UserApplicationRoleId) + 1;
    
                foreach (var u in userApplicationRolesToAdd)
                {
                    UserApplicationRole userApplicationRole = new UserApplicationRole
                    {
                        UserApplicationRoleId = startingId,
                        UserID = copyToUser.UserId,
                        UserGroupId = copyToUser.ParentId.Value,
                        ApplicationRoleId = u.ApplicationRoleId,
                        ExpiryDate = u.ExpiryDate,
                        IsEnabled = u.IsEnabled
                    };
    
                    userApplicationRoles.Add(userApplicationRole);
                    startingId++;
                }     
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 2015-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多