流畅的NHibernate多对多映射,具有自动生成的pk而不是复合键 [英] Fluent NHibernate Many-to-many mapping with auto-generated pk instead of composite key

查看:95
本文介绍了流畅的NHibernate多对多映射,具有自动生成的pk而不是复合键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.fluent NHibernate在Oracle 9.2数据库中映射表,正在使用.NET中的RoleProvider.

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.

这是我的UserMap:

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();
        }

还有我的RoleMap:

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();
    }

但是,这给了我错误:

程序集"FluentNHibernate,版本= 1.0.0.593,Culture = neutral,PublicKeyToken = 8aa435e3cb308880"中的类型"FluentNHibernate.Cfg.FluentConfigurationException"未标记为可序列化.

是否有一个简单的修复程序允许此HasMayToMany使用我的PersistentObjectMap扩展?我在想可能需要为此多对多关系添加一个约定,但是我不知道从哪里开始,因为我才刚刚开始使用NHibernate和Fluent NHibernate.

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.

编辑:我认为我在这里找到了可能的解决方案:

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.

我创建了上述博客文章中提到的链接实体,并下载了最新的二进制文件(1.0.0.623).
这帮助我发现问题在于设置延迟加载并尝试在全新会话中向用户对象添加角色.

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.

我修改了代码,以将OpenSession移至HttpModule的BeginRequest,如

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.

这似乎已经解决了我的大部分问题,但是我现在收到一条错误消息,提示无法插入集合"到USR_ROLE表中.而且我想知道上面的代码是否可以与如下描述的UserRoleMap一起使用:

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关于多对多关系的文档建议像在ERD中一样,创建一个对象来维护一对多/多对一.我敢肯定,使用常规命名标准会容易得多,但是我必须坚持使用某些缩写和奇数(而且并非总是正确实现)的约定.

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.

推荐答案

为解决此问题,我为UserRole创建了一个实体,映射和存储库.而且,我有一个HasMany映射,而不是用户和角色实体中的HasManyToMany映射.有点奇怪,因为我现在有:

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;}

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

这行得通,但是,我不确定100%为什么行得通,而HasManyToMany却行不通.

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

这篇关于流畅的NHibernate多对多映射,具有自动生成的pk而不是复合键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆