开发者

Fluent NHibernate Many-to-many mapping with auto-generated pk instead of composite key

开发者 https://www.devze.com 2022-12-19 02:36 出处:网络
I\'m working on a RoleProvider in .NET, using Fluent NHibernate to map tables in an Oracle 9.2 database.

I'm working on a RoleProvider in .NET, using Fluent NHibernate to map tables in an Oracle 9.2 database.

The problem is that the many-to-many table connecting users and roles uses a primary key generated from a sequence, as opposed to a composite key. I can't really change this, because I'm writing it to be implemented in a larger existing system.

Here is my UserMap:

        public UserMap()
        {
            this.Table("USR");
            HasMany(x => x.Memberships).Cascade.All()
                .Table("MEMBERSHIP").Inverse().LazyLoad();
            HasManyToMany(x => x.Roles)
                .Table("USR_ROLE")
                .Cascade.SaveUpdate()
                .ParentKeyColumn("USR_ID")
                .ChildKeyColumn("ROLE_ID")
                .Not.LazyLoad();
        }

And my RoleMap:

    public RoleMap()
    {
        this.Table("ROLE");            
        Map(x => x.Description).Column("ROLE_NAME");
        Map(x => x.Comment).Column("ROLE_COMMENT");
        HasManyToMany(x => x.Users)
            .Table("USR_ROLE")
            .ParentKeyColumn("ROLE_ID")
            .ChildKeyColumn("USR_ID")
            .Inverse();
    }

Yet, this is giving me the error:

Type 'FluentNHibernate.Cfg.FluentConfigurationException' in assembly 'FluentNHibernate, Version=1.0.0.593, Culture=neutral, PublicKeyToken=8aa435e3cb308880' is not marked as serializable.

Is there a simple fix to allow this HasMayToMany to use my PersistentObjectMap extension? I'm thinking I may have to add a convention for this many-to-many relationship, but I don't know where to start with that, since I've just started using NHibernate and Fluent NHibernate only recently.

I've been working on this problem for a while and I can't seem to find a solution. Any help would be much appreciated. Thanks.

EDIT: I think I've found a possible solution here: http://marekblotny.blogspot.com/2009/02/fluent-nhbernate-and-collections.html

I'll try the above method of creating an entity and a class map开发者_开发技巧 for the linking table and post my findings.

EDIT 2: I created a linking entity as mentioned in the above blog post and downloaded the newest binaries (1.0.0.623).

This helped me discover that the issue was with setting lazy load and trying to add roles to the user object in a completely new session.

I modified the code to move OpenSession to the BeginRequest of an HttpModule as described here. After doing this, I changed my data access code from wrapping the open session in a using statement, which closes the session when it is finished, to getting the current session and wrapping only the transaction in a using statement.

This seems to have resolved the bulk of my issue, but I am now getting an error that says "Could not insert collection" into the USR_ROLE table. And I'm wondering if the above code should work with a UserRoleMap described as:

    public UserRoleMap()
    {
        this.Table("USR_ROLE"); 

        /* maps audit fields id, created date/user, updated date/user */
        this.PersistentObjectMap("USR_ROLE"); 

        /* Link these tables */
        References(x => x.Role).Column("ROLE_ID");
        References(x => x.User).Column("USR_ID");
    }

Hibernate's documentation for many-to-many relationship suggests creating an object to maintain a one-to-many/many-to-one, as in an ERD. I'm sure this would be much easier with conventional naming standards, but I have to stick with certain abbreviations and odd (and not always properly-implemented) conventions.


To fix this, I created an Entity, Mapping, and Repository for UserRole. And, instead of HasManyToMany mapping in the User and Role Entities, I have a HasMany mapping. It's a little weird, because I now have:

IList<UserRole> UserRoles {get; protected set;}

and IList<Role> Roles { get{ return UserRoles.Select(u => u.Role).ToList(); } }

This works, however, I'm not 100% sure why this works and the HasManyToMany doesn't.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号