2015-02-09 60 views
0

可以说,我有这个数据库架构NHibernate的Queryover多层次模型

[User] -1----n-> [Resource] -1----n-> [ResourceVersion] 

,我想通过用户名一个数据库往返供用户选择此使用NHibernate,但选择与未来没有按工作resourceVersions。如何使用期货在一次往返中保存收藏品?我更喜欢QueryOver或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> 
... 

根据视觉工作室INTELLI仅跟踪查询执行是这样的一种:

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; 

和在@ p 0为用户名我传递给方法。没有任何版本的迹象,我觉得有点奇怪。

+0

什么不工作呢? – 2015-02-09 03:08:37

+0

它根本不要求DB包含版本的任何查询。资源上的版本集合抛出延迟初始化异常。 – LightCZ 2015-02-09 03:12:34

+0

你可以显示你的映射文件吗? – Najera 2015-02-09 04:33:13

回答

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

我曾尝试过,但因SingleOrDefault()部分失败,因为结果不止一个user.i认为当我在一个查询中加载多个集合时,结果将是笛卡尔积。假设一个用户有2个资源,每个资源都有...可以说5个版本...这个场景的结果是(没有单个或默认的)10个用户每个都有资源懒惰可初始化的异常......更不用说了版本... – LightCZ 2015-02-11 11:52:30

+0

啊对不起。忘了设置变压器,固定 – Firo 2015-02-11 15:40:30

+0

好吧,所以我试着与distinctRootEntitiy变压器它不会选择用户。资源这个部分在SQL查询没有加入资源和版本上的迹象,所以user.Resources抛出延迟初始化异常 – LightCZ 2015-02-13 13:50:43