假设我有这个数据库架构
[User] -1----n-> [Resource] -1----n-> [ResourceVersion]
并且我想在一个数据库中使用Nhibernate为用户按用户名选择此选项但选择resourceVersions并且将来无效。如何使用Futures在一次往返中水合收集?我更喜欢QueryOver或Criteria而不是HQL。我正在使用nHibernate 4.0。
public virtual User GetUserResources(string username)
using (ISession session = GetSession())
{
Resource resAlias = null;
User userAlias = null;
var result = session.QueryOver(() => userAlias)
.JoinQueryOver(x => x.Resources, () => resAlias)
.JoinQueryOver(() => resAlias.Versions)
.Where(() => userAlias.Login == username)
.Future<User>(); //THIS DOESNT WORK
var user = session.QueryOver<User>()
.Fetch(x => x.Resources).Eager
.Where(x => x.Login == username)
.SingleOrDefault<User>();//with this i can select user and resources
return user;
}
映射:
USER:
<class name="User" table="[User]">
<id name="Id" type="Int32">
<generator class="identity" />
</id>
<property name="Name">
<column name="Name" sql-type="varchar(100)" />
</property>
<property name="Email">
<column name="Email" sql-type="varchar(255)" />
</property>
<property name="Login">
<column name="Login" sql-type="varchar(50)" />
</property>
<property name="PasswordHash">
<column name="PasswordHash" sql-type="varchar(100)" />
</property>
<property name="CreateDate">
<column name="CreateDate" sql-type="datetime" />
</property>
<bag name="Resources" lazy="true" fetch="subselect" cascade="all-delete-orphan">
<key column="UserResource"/>
<one-to-many class="Resource" />
</bag>
</class>
RESOURCE:
<class name="Resource" table="[Resource]" abstract="true">
<id name="Id" type="Int64">
<generator class="identity" />
</id>
<discriminator column="Type"
not-null="true"
type="String" />
<bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="true" order-by="ActiveFrom DESC">
<key column="ResourceId" not-null="true"/>
<one-to-many class="Version"/>
</bag>
<subclass name="Resource1" discriminator-value="Res1" />
<subclass name="Resource2" discriminator-value="Res2" />
</class>
VERSION:
<class name="Version" table="Version">
<id name="Id" type="long">
<!--<column name="Id" sql-type="bigint"/>-->
<generator class="identity" />
</id>
...
<many-to-one name="Resource"
class="Resource"
column="ResourceId"/>
<property name="ActiveFrom">
<column name="ActiveFrom" sql-type="datetime" />
</property>
<property name="ActiveTo">
<column name="ActiveTo" sql-type="datetime"/>
</property>
...
只有在visual studio中根据智能跟踪执行的查询是这样的:
SELECT this_.Id AS Id0_1_ ,
this_.Name AS Name0_1_ ,
this_.Email AS Email0_1_ ,
this_.Login AS Login0_1_ ,
this_.PasswordHash AS Password5_0_1_ ,
this_.CreateDate AS CreateDate0_1_ ,
resource2_.UserResource AS UserResource3_ ,
resource2_.Id AS Id3_ ,
resource2_.Id AS Id4_0_ ,
resource2_.Type AS Type4_0_
FROM
[User] this_ LEFT OUTER JOIN [Resource] resource2_
ON this_.Id
=
resource2_.UserResource
WHERE this_.Login
=
@p0;
并且@ p0是我传递给方法的用户名。没有版本的迹象,我觉得有点奇怪。
答案 0 :(得分:0)
你永远不会迭代未来返回的IEnumerable,所以它永远不会执行它。我现在没有NH 4.0,但以下可能有效
public virtual User GetUserWithResources(string username)
{
using (ISession session = GetSession())
{
Resource resAlias = null;
return session.QueryOver<User>()
.Where(user => user.Login == username)
.Left.JoinQueryOver(x => x.Resources)
.Left.JoinQueryOver(res => res.Versions)
.TransformUsing(Transformers.DistinctRootEntity)
.List<User>().SingleOrDefault();
}
}