简体   繁体   中英

NHibernate mapping by code ManyToMany

Problem

I'm using NHibernate mapping by code to map relationships. In this case I map users to roles to privileges. Users and roles are in an:m relationship, same for roles and privileges. The SQL DB is SQL Server. If I remove the n:m relationshop from my code between roles and privileges, my code works. If it is there, I get the following MappingException :

Could not determine type for: 
Dtp.Entities.AppPrivilege, Dtp.Entities, for columns: NHibernate.Mapping.Column(id)

I can't find the source of the difference, since the same relationshop between users and roles works without a hitch. Can anyone shed a light on this problem please?

The precise part which produces the error (it goes away if commented out) is the Bag for AppRole.AppPrivileges .

MyCode

AppUser

~~~ Table ~~~

AppUserId, uniqueidentifier, not null
//some omitted properties

~~~ Entity ~~~

public class AppUser {
    public virtual Guid AppUserId { get; set; }
    //some omitted properties
    public virtual IList<AppRole> AppRoles { get; set; }
}

~~~ Mapping ~~~

public class AppUserMap : ClassMapping<AppUser>
{
    public AppUserMap()
    {
        Table("AppUser");
        Schema("dbo");
        Lazy(true);
        Id(x => x.AppUserId, map => map.Generator(Generators.GuidComb));
        //some omitted properties
        Bag(x => x.AppRoles,
            colmap => {
                colmap.Cascade(Cascade.None);
                colmap.Table("AppUser_AppRole");
                colmap.Key(x => x.Column("AppUserId"));
            },
            map => map.ManyToMany(many => many.Column("AppRoleId")));
    }
}

AppUser_AppRole

~~~ Table ~~~

AppUserId, uniqueidentifier, not null
AppRoleId, uniqueidentifier, not null

AppRole

~~~ Table ~~~

AppRoleId, uniqueidentifier, not null
//some omitted properties

~~~ Entity ~~~

public class AppRole{
    public virtual Guid AppRoleId { get; set; }
    //some omitted properties
    public virtual IList<AppUser> AppUsers { get; set; }
    public virtual IList<AppPrivilege> AppPrivileges { get; set; }
}

~~~ Mapping ~~~

public class AppRoleMap : ClassMapping<AppRole> {

    public AppRoleMap()
    {
        Table("AppRole");
        Schema("dbo");
        Lazy(true);
        Id(x => x.AppRoleId, map => map.Generator(Generators.GuidComb));
        //some omitted properties
        Bag(x => x.AppUsers, 
            colmap => {
                colmap.Cascade(Cascade.None);
                colmap.Table("AppUser_AppRole");
                colmap.Key(x => x.Column("AppRoleId"));
            }, 
            map => map.ManyToMany(many => many.Column("AppUserId")));
        //The following definition produces the bug.
        Bag(x => x.AppPrivileges,
            colmap => {
                colmap.Cascade(Cascade.None);
                colmap.Table("AppRole_AppPrivilege");
                colmap.Key(x => x.Column("AppRoleId"));
            },
            map => map.ManyToMany(many => many.Column("AppPrivilegeId")));
    }
}

AppRole_AppPrivilege

~~~ Table ~~~

AppRoleId, uniqueidentifier, not null
AppPrivilegeId, uniqueidentifier, not null

AppPrivilege

~~~ Table ~~~

AppPrivilegeId, uniqueidentifier, not null
//some omitted properties

~~~ Entity ~~~

public class AppPrivilege {
    public virtual Guid AppPrivilegeId { get; set; }
    //some omitted properties
    public virtual IList<AppRole> AppRoles { get; set; }
}

~~~ Mapping ~~~

public class AppPrivilegeMap: ClassMapping<AppPrivilege> {

    public AppPrivilegeMap()
    {
        Table("AppPrivilege");
        Schema("dbo");
        Lazy(true);
        Id(x => x.AppPrivilegeId, map => map.Generator(Generators.GuidComb));
        //some omitted properties
        Bag(x => x.AppRoles,
            colmap => {
                colmap.Cascade(Cascade.None);
                colmap.Table("AppRole_AppPrivilege");
                colmap.Key(x => x.Column("AppPrivilegeId"));
            },
            map => map.ManyToMany(many => many.Column("AppRoleId")));
    }
}

The answer to this problem cannot be found in the files above. I just forgot to add the AppPrivilegeMap to the ModelMapper during NHibernateHelper.OnConfigure() .

Now the last task is to find out where to put the .Inverse(true) , so serializing an object won't result in an exception because of circular reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM