2010-03-01 86 views
1

我开始怀疑,如果我实际上太愚蠢的使用NHibernate。我目前使用FluentNHibernate来创建简单的数据库映射,这对我们来说很好。当单独处理我们的各种类时,我们能够读写所有这些类,执行更新等。然而,我的问题是试图建立一个查询,涉及比对实体类型的字段进行过滤更复杂的任何事情。一个很好的例子被示出below--CreateAlias和NHibernate加入类无w /没有映射关系

映射的相关部分:

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”与User对象有关。

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 []集合),因为有些情况下我们特别使用仅用于连接的表,但我们不希望浮动到中间层。所以学习如何参加孤立的课程对我们很重要。

+0

我不认为你太愚蠢。我认为nocoa的doco和使用是相当糟糕的。 – Mac 2011-07-06 04:22:16

回答

4

您的映射无法从User导航到RoleMap,但这正是您在Criteria API调用中所要做的。你有多个选项。这里有一对夫妇:

1)允许用户在您的映射中导航到RoleMap。这是最简单的,它是如何正常完成的。

2)使用两个查询,其中一个获取基于RoleMap到Role关系的UserIds列表,然后第二个查询获取这些UserIds的所有用户。

你说你不想在你的中间层有一个User.Roles集合,但是NHibernate应该存在于你的数据层中,而不是你的业务层。您可以允许NHibernate了解User.Roles,同时有效地将其隐藏在业务层中。

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