Search code examples
asp.net-mvc-3fluent-nhibernaterecordfluent

Deletion issue using fluent nhibernate in mvc 3


I've a layer name MVCTemplate.Common, having two folders Entities and Mappings. In Entities User.cs and Role.cs is as under respectively:

using System;
using System.Collections.Generic;

namespace MVCTemplate.Common.Entities
{
    public class User
    {
        public virtual Guid UserID { get; set; }
        public virtual string UserName { get; set; }
        public virtual string Password { get; set; }
        public virtual string FullName { get; set; }
        public virtual string Email { get; set; }
        public virtual TimeSpan LastLogin { get; set; }
        public virtual bool IsActive { get; set; }
        public virtual DateTime CreationDate { get; set; }
        public virtual IList<Role> UserInRoles { get; set; }

        public User()
        {
            UserInRoles = new List<Role>();
        }
    }
}

using System.Collections.Generic;

namespace MVCTemplate.Common.Entities
{
    public class Role
    {
        public virtual int? RoleID { get; set; }
        public virtual string RoleName { get; set; }
        public virtual bool IsActive { get; set; }
        public virtual string Description { get; set; }
        public virtual IList<User> Users { get; set; }
        //public virtual IList<RolePermission> RolePermission { get; set; }

        public Role()
        {
            Users = new List<User>();
        }

        public virtual void AddUsers(User _user)
        {
            _user.UserInRoles.Add(this);
            Users.Add(_user);
        }
    }
}

Now, In Mappings folder their mappings files is as under:

using FluentNHibernate.Mapping;
using MVCTemplate.Common.Entities;

namespace MVCTemplate.Common.Mappings
{
   public class RoleMap : ClassMap<Role>
    {
        public RoleMap()
        {
            Table("tblRoles");
            Id(role => role.RoleID).GeneratedBy.Identity();
            Map(role => role.RoleName).Not.Nullable();
            Map(role => role.IsActive).Not.Nullable();
            Map(role => role.Description).Not.Nullable();
            HasManyToMany(role => role.Users).Cascade.All().Table("tblUserInRoles");
            //HasMany(role => role.User);
            //HasMany(role => role.RolePermission);
        }
    }
}

using FluentNHibernate.Mapping;
using MVCTemplate.Common.Entities;

namespace MVCTemplate.Common.Mappings
{
    public class UserMap : ClassMap<User>
    {
        public UserMap()
        {
            Table("tblUsers");
            Id(user => user.UserID).GeneratedBy.Guid();
            Map(user => user.UserName).Not.Nullable();
            Map(user => user.Password).Not.Nullable();
            Map(user => user.FullName).Not.Nullable();
            Map(user => user.Email).Not.Nullable();
            //Map(user => user.LastLogin).Nullable();
            Map(user => user.IsActive).Not.Nullable();
            Map(user => user.CreationDate).Not.Nullable();
            HasManyToMany(user => user.UserInRoles).Cascade.All().Table("tblUserInRoles");
            //HasMany(user => user.UserInRoles);
        }
    }
}

Now, from controller, I got specific user object in user object and now want to delete it, the simple code is as under:

using System;
using System.Collections.Generic;
using System.Web.Mvc;
using MVCTemplate.BussinessLayer.Facade;
using MVCTemplate.Common.Entities;

namespace MVCTemplate.Web.Controllers
{
    public class HomeController : Controller
    {

        private UserManagement _userManagement;
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            _userManagement = new UserManagement();
            var oUser = _userManagement.GetUserBy(new Guid("4fb5856a-58d9-4b78-8d08-bce645bc93c7"));

            oUser.UserInRoles = new List<Role>();
            _userManagement.Delete(oUser);

            return View();
        }

        public ActionResult About()
        {
            return View();
        }
    }
}

Now, I just want to delete that user as this user is not exist in any role and there is no entry of it in its junction table(UserInRole). I initialize its Role collection to empty for Count=0, but after calling deleting method it throw an error with sqlQuery which is as under:

could not delete collection: [MVCTemplate.Common.Entities.User.UserInRoles#4fb5856a-58d9-4b78-8d08-bce645bc93c7][SQL: DELETE FROM tblUserInRoles WHERE User_id = @p0]

Note that in Junction table tblUserInRole there no field of that name User_id as mentioned in error, due to which in the inner exception it is telling that column name User_id not exist. But in junction table I have only two field 1) UserID and 2) RoleID.

Any suggestion how to resolve it?


Solution

  • looks like a mapping error to me. Change:

    HasManyToMany(user => user.UserInRoles).Cascade.All().Table("tblUserInRoles");
    

    To

    HasManyToMany(user => user.UserInRoles)
        .Cascade.All()
        .Table("tblUserInRoles")
        .ParentKeyColumn("UserID")
        .ChildKeyColumn("RoleID");