代码之家  ›  专栏  ›  技术社区  ›  bakasan

在没有映射关系的类上创建别名和nHibernate联接

  •  1
  • bakasan  · 技术社区  · 14 年前

    我开始怀疑我是否真的太笨了,不能用NHibernate。我目前正在使用FluentHibernate创建简单的DB映射,这对我们来说很好。当单独处理我们的各种类时,我们能够读写所有这些类,执行更新等。然而,我的问题是试图构建一个查询,该查询涉及到比筛选实体类型字段更复杂的内容。下面是一个很好的例子--

    映射的相关部分:

    public class UserMap : ClassMap<User> {
        Id(u => u.Id).Column("UserID").GeneratedBy.Identity();
        //other non-pertinent fields 
    }
    
    public class RoleMap : ClassMap<Role> {
        Id(r => r.Id).Column("RoleId").GeneratedByIdentity();
        //snip
    }
    
    public class RoleMapMap : ClassMap<RoleMap> {
        Id(rm => rm.Id).Column("RoleMapId").GeneratedByIdentity();
        Map(rm => rm.UserId);
        Map(rm => rm.RoleId);
        //snip
    }
    

    其目的是生成一个带有条件API的查询,以检索特定角色的所有用户——在高层,基于特定角色ID筛选角色映射,然后加入到用户中,并仅返回这些用户。

    尝试以下操作,但我对CreateAlias的使用显然有缺陷,因为运行时异常基本上告诉我它不知道下面的“rolemap”是什么,因为它与用户对象相关。

    var criteria = session.CreateCriteria<User>().
                    CreateAlias("RoleMap", "rm").
                    Add(Expression.Eq("rm.UserId", "UserId")).
                    Add(Expression.Eq("rm.RoleId", 99)).
                    SetResultTransformer(new 
                        DistinctRootEntityResultTransformer());
    
    var users = criteria.List<User>();
    

    有人能给我指个方向吗?我不希望编辑基础对象来公开集合——(例如user.roles[]集合),因为在某些情况下,我们专门为联接使用表,但不希望浮动到中间层。因此,学习如何加入孤立的班级对我们来说很重要。

    1 回复  |  直到 14 年前
        1
  •  4
  •   Michael Maddox    14 年前

    您的映射不包含从用户导航到角色映射的方法,但这正是您在标准API调用中要做的。你有多种选择。以下是一些:

    1)允许用户在映射中导航到角色映射。这是最简单的,也是通常的做法。

    2)使用两个查询,一个根据角色映射到角色的关系获取用户ID列表,另一个查询获取这些用户ID的所有用户。

    你说你不想要一个用户。角色集合在你的中间层,但是NHibernate应该存在于你的数据层,不一定存在于你的业务层。您可以允许nhibernate了解用户角色,同时有效地将其隐藏在您的业务层中。

    加入独立的类并不是构建ORM的真正目的。窗体是为加入相关类而构建的。相关类通常映射到数据库级别的相关表。要加入独立的类,您需要执行上面的选项2,其中运行多个查询和/或解决自定义代码中缺少关系的问题。