How to Update a Many To Many relationship

こ雲淡風輕ζ 提交于 2021-01-28 06:50:59

问题


I'm have this Many To Many Relationship:

public class Role
{
    [Key]
    public int role_Id { get; set; }
    public string Name { get; set; }
    public ICollection<LoginModel> Users { get; set; }

    public ICollection<Permission> Permissions { get; set; }

    public Role()
    {
        Users = new List<LoginModel>();
        Permissions = new Collection<Permission>();

    }
}

public class Permission
{
    [Key]
    public int permi_Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Role> Roles { get; set; }

    public Permission()
    {
        Roles = new Collection<Role>();
    }
}

In my DbContext

modelBuilder.Entity<Role>().HasMany(r => r.Permissions).WithMany(p => p.Roles)
                .Map(
                    m =>
                    {
                        m.MapLeftKey("role_id");
                        m.MapRightKey("per_id");
                        m.ToTable("roles_permissions");
                    }
                );

So I have this third table (Many To Many) and I want to Update the permissions (Add or remove) for a specific Role ( The permissions are taken from a CheckedListBox).I'm trying to update the third table with this code but it does not work

//Get the specific role

Role role = (from s in db.Roles
             where s.Name == txt_modificar_nombre.Text
             select s).FirstOrDefault<Role>();

//Get the permissions from that specific role

var permissions = db.Roles.Where(r => r.Name == txt_modificar_nombre.Text)
                 .SelectMany(r => r.Permissions);

//erase all the old permissions (like reset the permissions)

foreach (var permission in permissions)
{
    role.Permissions.Remove(permission);//reset the permissions
    for (int i = 0; i < checkedListBox_modificar_permissions.Items.Count; i++)
    {
        if ((string)checkedListBox_modificar_permissions.Items[i] == permission.Name)
        {
            checkedListBox_modificar_permissions.SetItemChecked(i, true);
        }
    }
}

//Insert the new permissions (checked=true in the checkedList)

foreach (var item in checkedListBox_modificar_permissions.CheckedItems)
{
    Permission permission = HandyClass.GetPermission(item.ToString(), db);
    role.Permissions.Add(permission);
    db.SaveChanges();
}  

I get this error in the line db.SaveChanges();

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.


回答1:


The problem is that the collection role.Permissions is not loaded before you make changes to it. This is because

  1. It cant't be lazy loaded. To enable lazy loading, add the virtual modifier:

    public virtual ICollection<Permission> Permissions
    
  2. It isn't loaded eagerly, which can be done by Include:

    from s in db.Roles.Include(r => r.Permissions) ...
    

So you should do either of these, or both. Eager loading is preferred, because it grabs the data in one query.

The exception isn't too clear. It refers to case where entities don't have primitive foreign key properties, only collections and references to objects. But this only applies to 1-n associations. In the classical Order-Orderline association, Orderline may have

public virtual Order Order { get; set; }

which makes this an independent association

and also

[ForeignKey("Order"]
public virtual int OrderId { get; set; }

which turns it into a foreign key association.

But in a many-to-many association the entities can't have these primitive properties, because the foreign keys are in the hidden junction table roles_permissions. EF could give a more descriptive exception message here.



来源:https://stackoverflow.com/questions/21502829/how-to-update-a-many-to-many-relationship

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!