2009-08-13 64 views
1

考慮下面的映射文件,其中TemporaryAccessOpenCommand和TemporaryAccessCloseCommand無論是從基類繼承的命令NHibernate的查詢問題

<class name="Command" table="xxx_Commands" lazy="false"> 
<id name="Id" type="Int32" unsaved-value="0"> 
    <generator class="identity"/> 
</id> 
<property name="BeginDate" /> 
<property name="EndDate" /> 
<component name="Result" class="CommandResult"> 
    <property name="Status" column="ResultStatus"/> 
    <property name="Details" column="ResultDetails" /> 
</component> 

<many-to-one name="Requestor" class="xxx.Domain.SessionInfo, xxx.Domain" column="SessionInfoId" lazy="false" /> 

<joined-subclass name="xxx.TemporaryAccess.Commands.TemporaryAccessCloseCommand, xxx.TemporaryAccess" table="xxx_Commands_TemporaryAccess_Close"> 
    <key column="CommandId"/> 
</joined-subclass> 

<joined-subclass name="xxx.TemporaryAccess.Commands.TemporaryAccessOpenCommand, xxx.TemporaryAccess" table="xxx_Commands_TemporaryAccess_Open"> 
    <key column="CommandId"/> 
    <many-to-one name="EndUser" ...... /> 
    <property name="Reason"/> 
    <property name="AccessRight"/> 
    <property name="AccessType"/> 
    <bag name="CloseAccessCommands" cascade="all" lazy="false"> 
    <key column="OpenCommandId"/> 
    <one-to-many class="xxx.TemporaryAccess.Commands.TemporaryAccessCloseCommand, xxx.TemporaryAccess"/> 
    </bag> 
</joined-subclass> 

什麼是NHibernate的查詢檢索每個OpenAccessCommand沒有成功CloseAccessCommand?

我嘗試這樣做:

public IList<TemporaryAccessOpenCommand> FindOpenCommandsWithoutSucceededCloseCommand() 
    { 
     return this.HibernateTemplate.ExecuteFind<TemporaryAccessOpenCommand>(delegate(ISession session) 
     { 
      return session.CreateCriteria(typeof(TemporaryAccessOpenCommand)) 
       .CreateCriteria("CloseAccessCommands") 
       .Add(Expression.Not(Expression.Eq("Result.Status", CommandStatus.Succeeded))) 
       .List<TemporaryAccessOpenCommand>(); 
     }); 
    } 

但它會返回具有拖CloseCommand(一個失敗,一個成功)的OpenAccessCommand時,它應該返回一個空列表。

感謝您的幫助(和原諒我的英語很差)

回答

0

我設法得到的東西以這種方式工作(我很開放的建議,如果它不是最好的方法)

public IList<TemporaryAccessOpenCommand> FindOpenCommandsWithoutSucceededCloseCommand() 
    { 
     return this.HibernateTemplate.ExecuteFind<TemporaryAccessOpenCommand>(delegate(ISession session) 
     { 
      string sql = string.Format(@" 
             (
              SELECT temp_c.OpenCommandId 
              FROM VSA2_Commands_TemporaryAccess_Close temp_c 
                INNER JOIN VSA2_Commands c 
                 ON temp_c.CommandId = c.Id 
              WHERE c.ResultStatus = {0} 
             ) AS OpenCommandId" 

             , (int)CommandStatus.Succeeded); 

      var subCriteria = DetachedCriteria.For<TemporaryAccessCloseCommand>(); 
      subCriteria = subCriteria.SetProjection(Projections.SqlProjection(sql, new string[] { "OpenCommandID" }, new IType[] { NHibernateUtil.Int32 })); 


      return session.CreateCriteria(typeof(TemporaryAccessOpenCommand)) 
       .Add(Expression.Eq("Result.Status", CommandStatus.Succeeded)) 
       .Add(Subqueries.PropertyNotIn("Id", subCriteria)) 
       .List<TemporaryAccessOpenCommand>(); 
     }); 
    }