Nhibernate查询问题

时间:2009-08-13 11:56:01

标签: nhibernate criteria

考虑以下映射文件,其中TemporaryAccessOpenCommand和TemporaryAccessCloseCommand都从基类Command继承

<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>

检测没有成功的CloseAccessCommand的每个OpenAccessCommand的nhibernate查询是什么?

我试过了:

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

但是当它应该返回一个空列表时,它将返回一个OpenAccessCommand,它有两个CloseCommand(一个失败,一个成功)。

感谢您的帮助(并原谅我可怜的英语)

1 个答案:

答案 0 :(得分: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>();
        });
    }