流畅的NHibernate使用自动生成的pk而不是复合键进行多对多映射

时间:2010-02-02 16:50:35

标签: c# asp.net nhibernate orm fluent-nhibernate

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

问题是连接用户和角色的多对多表使用从序列生成的主键,而不是复合键。我无法改变这一点,因为我正在编写它以在更大的现有系统中实现。

这是我的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();
        }

我的角色地图:

    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中输入'FluentNHibernate.Cfg.FluentConfigurationException',Version = 1.0.0.593,Culture = neutral,PublicKeyToken = 8aa435e3cb308880'未标记为可序列化。

是否有一个简单的修复方法允许此HasMayToMany使用我的PersistentObjectMap扩展?我想我可能不得不为这种多对多关系添加一个约定,但我不知道从哪里开始,因为我刚刚开始使用NHibernate和Fluent NHibernate。

我一直在研究这个问题,我似乎无法找到解决方案。 任何帮助将非常感激。感谢。

编辑:我想我在这里找到了一个可能的解决方案:http://marekblotny.blogspot.com/2009/02/fluent-nhbernate-and-collections.html

我将尝试上面为链接表创建实体和类映射的方法,并发布我的发现。

编辑2:我创建了一个链接实体,如上面的博文所述,并下载了最新的二进制文件(1.0.0.623)。 这有助于我发现问题在于设置延迟加载并尝试在全新会话中向用户对象添加角色。

我修改了代码,将OpenSession移动到HttpModule的BeginRequest,如here所述。执行此操作后,我将数据访问代码更改为在using语句中包含open会话,该语句在完成时关闭会话,以获取当前会话并仅在using语句中包装事务。

这似乎解决了我的大部分问题,但我现在收到一条错误,上面写着“无法插入集合”到USR_ROLE表中。我想知道上面的代码是否适用于描述为:

的UserRoleMap
    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中一样。我确信使用传统的命名标准会更容易,但我必须坚持使用某些缩写和奇数(并且不总是正确实现)约定。

1 个答案:

答案 0 :(得分:0)

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

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

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

但是,我不能100%确定为什么这样做而且HasManyToMany没有。