Search code examples
c#model-view-controllermany-to-manyef-model-firstef-model-builder

I want to Add multiple Roles at the time of registeration with many to many relationship using EF Models in MVC


I have user registration table with roles, i want to register new user with multiple roles via Many-to-Many Ef Models Generated Models.

I have issue while registering users, New Roles are inserted into roles table and than these newly added roles inserted into user_has_roles (Junction) table.

Here is Registration Form Image

enter image description here

Here is Database Many to Many Relational Tables Image

enter image description here

Here is EF Model Table Image

enter image description here

I m sharing some Code that i have write

Auto Generated Model Classes user.cs

public partial class user
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public user()
    {
        this.user_role = new HashSet<user_role>();
    }

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int user_id { get; set; }
    public string user_email { get; set; }
    public string user_full_name { get; set; }
    public string user_password { get; set; }
    public string user_phone { get; set; }
    public string user_mobile { get; set; }
    public Nullable<int> country_id { get; set; }
    public Nullable<int> city_id { get; set; }

    public virtual city city { get; set; }
    public virtual country country { get; set; }
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<user_role> user_role { get; set; }
}

user_role.cs

public partial class user_role
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public user_role()
    {
        this.users = new HashSet<user>();
    }

    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int user_role_id { get; set; }
    public string user_role_name { get; set; }
    public Nullable<int> user_role_status { get; set; }
    public string user_role_description { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<user> users { get; set; }
}

Here is my db context class (Auto generated

AccountDb.cs

public partial class SaholatEntities : DbContext
{
    public SaholatEntities()
        : base("name=SaholatEntities")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<city> cities { get; set; }
    public virtual DbSet<country> countries { get; set; }
    public virtual DbSet<sysdiagram> sysdiagrams { get; set; }
    public virtual DbSet<user> users { get; set; }
    public virtual DbSet<user_role> user_role { get; set; }

    public virtual int sp_alterdiagram(string diagramname, Nullable<int> owner_id, Nullable<int> version, byte[] definition)
    {
        var diagramnameParameter = diagramname != null ?
            new ObjectParameter("diagramname", diagramname) :
            new ObjectParameter("diagramname", typeof(string));

        var owner_idParameter = owner_id.HasValue ?
            new ObjectParameter("owner_id", owner_id) :
            new ObjectParameter("owner_id", typeof(int));

        var versionParameter = version.HasValue ?
            new ObjectParameter("version", version) :
            new ObjectParameter("version", typeof(int));

        var definitionParameter = definition != null ?
            new ObjectParameter("definition", definition) :
            new ObjectParameter("definition", typeof(byte[]));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_alterdiagram", diagramnameParameter, owner_idParameter, versionParameter, definitionParameter);
    }

    public virtual int sp_creatediagram(string diagramname, Nullable<int> owner_id, Nullable<int> version, byte[] definition)
    {
        var diagramnameParameter = diagramname != null ?
            new ObjectParameter("diagramname", diagramname) :
            new ObjectParameter("diagramname", typeof(string));

        var owner_idParameter = owner_id.HasValue ?
            new ObjectParameter("owner_id", owner_id) :
            new ObjectParameter("owner_id", typeof(int));

        var versionParameter = version.HasValue ?
            new ObjectParameter("version", version) :
            new ObjectParameter("version", typeof(int));

        var definitionParameter = definition != null ?
            new ObjectParameter("definition", definition) :
            new ObjectParameter("definition", typeof(byte[]));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_creatediagram", diagramnameParameter, owner_idParameter, versionParameter, definitionParameter);
    }

    public virtual int sp_dropdiagram(string diagramname, Nullable<int> owner_id)
    {
        var diagramnameParameter = diagramname != null ?
            new ObjectParameter("diagramname", diagramname) :
            new ObjectParameter("diagramname", typeof(string));

        var owner_idParameter = owner_id.HasValue ?
            new ObjectParameter("owner_id", owner_id) :
            new ObjectParameter("owner_id", typeof(int));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_dropdiagram", diagramnameParameter, owner_idParameter);
    }

    public virtual ObjectResult<sp_helpdiagramdefinition_Result> sp_helpdiagramdefinition(string diagramname, Nullable<int> owner_id)
    {
        var diagramnameParameter = diagramname != null ?
            new ObjectParameter("diagramname", diagramname) :
            new ObjectParameter("diagramname", typeof(string));

        var owner_idParameter = owner_id.HasValue ?
            new ObjectParameter("owner_id", owner_id) :
            new ObjectParameter("owner_id", typeof(int));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<sp_helpdiagramdefinition_Result>("sp_helpdiagramdefinition", diagramnameParameter, owner_idParameter);
    }

    public virtual ObjectResult<sp_helpdiagrams_Result> sp_helpdiagrams(string diagramname, Nullable<int> owner_id)
    {
        var diagramnameParameter = diagramname != null ?
            new ObjectParameter("diagramname", diagramname) :
            new ObjectParameter("diagramname", typeof(string));

        var owner_idParameter = owner_id.HasValue ?
            new ObjectParameter("owner_id", owner_id) :
            new ObjectParameter("owner_id", typeof(int));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<sp_helpdiagrams_Result>("sp_helpdiagrams", diagramnameParameter, owner_idParameter);
    }

    public virtual int sp_renamediagram(string diagramname, Nullable<int> owner_id, string new_diagramname)
    {
        var diagramnameParameter = diagramname != null ?
            new ObjectParameter("diagramname", diagramname) :
            new ObjectParameter("diagramname", typeof(string));

        var owner_idParameter = owner_id.HasValue ?
            new ObjectParameter("owner_id", owner_id) :
            new ObjectParameter("owner_id", typeof(int));

        var new_diagramnameParameter = new_diagramname != null ?
            new ObjectParameter("new_diagramname", new_diagramname) :
            new ObjectParameter("new_diagramname", typeof(string));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_renamediagram", diagramnameParameter, owner_idParameter, new_diagramnameParameter);
    }

    public virtual int sp_upgraddiagrams()
    {
        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("sp_upgraddiagrams");
    }
}

Here is my Controller Method to register User (POST)

    //post register
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Register(AccountVM obj)
    {
        if(ModelState.IsValid)
        {
            // insert Data into user variable array from obj viewmodel
            var user = new user()
            {
                user_email = obj.user_email,
                user_full_name = obj.user_full_name,
                user_password = obj.user_password,
                user_phone = obj.user_phone,
                user_mobile = obj.user_mobile,
                country_id = obj.country_id,
                city_id = obj.city_id
            };
            var user_roles = new user_role();

            AccountDb.users.Add(user);

            // insert Data into user_has_role variable array from obj viewmodel
            foreach(var item in obj.selectedRoleList)
            {
                user_roles.user_role_id = Convert.ToInt32(item);

                user_roles.users.Add(new user() { user_id = obj.user_id });

                user.user_role.Add(new user_role() { user_role_id = Convert.ToInt32(item) });

            }


            if (AccountDb.SaveChanges() > 0)
            {
                TempData["errorMsg"] = "save";
                return RedirectToAction("Index");
            }
            else
            {
                TempData["errorMsg"] = "queryError";
                ViewBag.country_id = new SelectList(AccountDb.countries, "country_id", "country_name");
                AccountVM objRole = new AccountVM();
                objRole.getRoleList = AccountDb.user_role.ToList();
                return View(objRole);
            }
        }
        else
        {
            TempData["errorMsg"] = "modelError";
            ViewBag.country_id = new SelectList(AccountDb.countries, "country_id", "country_name");
            AccountVM objRole = new AccountVM();
            objRole.getRoleList = AccountDb.user_role.ToList();
            return View(objRole);
        }
    }

I want to Register User with multiple roles and roles are already define in roles table select by multi-select, please help me out

when i registered the user with 1 role, new role added to role table and than newly added role assigned to user (Only role_id added to role table), and if i assign 2 roles than 2 will be added to roles table

EDITED Image of Junction table after registration

Image of user_role table


Solution

  • I solved my issue by doing this

    //post register
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Register(AccountVM obj)
    {
        if(ModelState.IsValid)
        {
            // insert Data into user variable array from obj viewmodel
            var user = new user()
            {
                user_email = obj.user_email,
                user_full_name = obj.user_full_name,
                user_password = obj.user_password,
                user_phone = obj.user_phone,
                user_mobile = obj.user_mobile,
                country_id = obj.country_id,
                city_id = obj.city_id
            };
            AccountDb.users.Add(user);
    
            // insert Data into user_has_role variable array from obj viewmodel
            foreach(var item in obj.selectedRoleList)
            {
                int id = Convert.ToInt32(item);
                user_role _user_role = AccountDb.user_role.FirstOrDefault(r => r.user_role_id == id);
    
                _user_role.users.Add(user);
                user.user_role.Add(_user_role);
            }
    
            if (AccountDb.SaveChanges() > 0)
            {
                TempData["errorMsg"] = "save";
                return RedirectToAction("Index");
            }
            else
            {
                TempData["errorMsg"] = "queryError";
                ViewBag.country_id = new SelectList(AccountDb.countries, "country_id", "country_name");
                AccountVM objRole = new AccountVM();
                objRole.getRoleList = AccountDb.user_role.ToList();
                return View(objRole);
            }
        }
        else
        {
            TempData["errorMsg"] = "modelError";
            ViewBag.country_id = new SelectList(AccountDb.countries, "country_id", "country_name");
            AccountVM objRole = new AccountVM();
            objRole.getRoleList = AccountDb.user_role.ToList();
            return View(objRole);
        }
    }