【问题标题】:Nhibernate Criterias inner join subqueryNhibernate Criterias内部连接子查询
【发布时间】:2012-03-14 12:58:07
【问题描述】:

我试图在 Nhibernate ICriteria 中复制以下 sql

    SELECT DISTINCT AP.ID
FROM ActivityParts AP
    INNER JOIN ActivityBookings AB ON AB.ActivityPartID = AP.ID
    INNER JOIN OrderPartBookings OPB ON OPB.ActivityBookingID = AB.ID
    INNER JOIN OrderParts OP ON OP.ID = OPB.OrderPartID
    INNER JOIN Orders O ON O.ID = OP.OrderID
    LEFT JOIN Invoices I ON I.ID = (SELECT TOP 1 ID FROM Invoices WHERE OrderReferenceID = OP.ID AND Cancelled = 0 ORDER BY Created DESC)
WHERE
    O.OrderStatus != 'Cancelled'
    AND OP.Payed = 0
    AND (I.ID IS NOT NULL AND DATEADD(Day,1, I.DueDate) < @date)

到目前为止,我已经设法得到以下信息(注意:我没有对其进行分析,所以我不太确定 sql 通过标准变得多么相似):

var invoiceSubCrit = DetachedCriteria.For<Invoice>()
            .Add(Restrictions.Eq("Cancelled", false))
            .Add(Restrictions.EqProperty("OrderReference", "OP.ID"))
            .AddOrder(NhOrder.Desc("Created"))
            .SetProjection(Projections.Property("DueDate"))
            .SetMaxResults(1);

        var crit = Session.CreateCriteria<OrderPart>("OP")
            .CreateCriteria("OP.Bookings", "AB", JoinType.InnerJoin)
            .CreateCriteria("OP.Order", "O", JoinType.InnerJoin)
            .CreateCriteria("AB.ActivityPart", "AP", JoinType.InnerJoin)
            .Add(NhExpression.Eq("AP.ID", ActivityID))
            .Add(NhExpression.Eq("OP.Payed", false))
            .Add(NhExpression.Not(NhExpression.Eq("O.OrderStatus", OrderStatus.Cancelled)))
            .Add(NhExpression.Not(NhExpression.Eq("AB.Status", QueueStatus.Reserve)))
            .Add(Subqueries.Lt(DateTime.Now.Date.AddDays(1), invoiceSubCrit))
            .SetResultTransformer(new DistinctRootEntityResultTransformer());

更新: 得到了一些新信息并稍微重构了 sql。 更新:有一个半工作子查询,需要弄清楚如何正确设置它。

【问题讨论】:

  • 不要答案更新问题,发布答案,然后在答案中 发布解决方案。我已将您的更改回滚,因为在更新您的问题时,您已使下面的答案无效,并且您的 answer 不是答案,它只是在说“嘿,我修好了,请看那里”。以后请尽量遵守。

标签: sql fluent-nhibernate subquery icriteria nhibernate-criteria


【解决方案1】:

终于让它工作了,并用我的情况下的最终工作版本更新了我的标准代码。我不知道这与我的原始 SQL 代码到底有多接近,但最重要的是结果接缝相同。

var invoiceSubCrit = DetachedCriteria.For<Invoice>()
            .Add(Restrictions.Eq("Cancelled", false))
            .Add(Restrictions.EqProperty("OrderReference.ID", "OP.ID"))
            .AddOrder(NhOrder.Desc("Created"))
            .SetProjection(Projections.Property("DueDate"))
            .SetMaxResults(1);

        var crit = Session.CreateCriteria<OrderPart>("OP")
            .CreateCriteria("OP.Bookings", "AB", JoinType.InnerJoin)
            .CreateCriteria("OP.Order", "O", JoinType.InnerJoin)
            .CreateCriteria("AB.ActivityPart", "AP", JoinType.InnerJoin)
            .Add(NhExpression.Eq("AP.ID", ActivityID))
            .Add(NhExpression.Eq("OP.Payed", false))
            .Add(NhExpression.Not(NhExpression.Eq("O.OrderStatus", OrderStatus.Cancelled)))
            .Add(NhExpression.Not(NhExpression.Eq("AB.Status", QueueStatus.Reserve)))
            .Add(Subqueries.Gt(DateTime.Now.Date, invoiceSubCrit))
            .SetResultTransformer(new DistinctRootEntityResultTransformer());

【讨论】:

    【解决方案2】:

    您不能在 from 子句中将条件与选择一起使用。尝试 hql 或过滤客户端

    更新:

    .Add(Restrictions.EqProperty("OrderReference.ID", "OP.ID"))
    // or 
    .Add(Restrictions.EqProperty("OrderReference", "OP"))
    

    【讨论】:

    • 我不确定我是否在这方面取得了任何进展,但如果我能弄清楚如何设置它,我已经做了一些看起来可能会起作用的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    相关资源
    最近更新 更多