苦苦挣扎,结合两个NHibernate查询,其中我与结果相交

时间:2012-10-10 21:42:38

标签: c# sql nhibernate

我已经制作了两个查询,这些查询都运行良好,但我真的很难理解如何将它们组合起来。我认为我最大的问题是我对查询使用了两种不同的语法,但我不确定如何在不使用“SQL-esque”标记的情况下表达我的第一个查询。

List<Task> tasksFromQueue = NHibernateSession.CreateQuery(
    "Select t from Task t, QueueLocation q where q.Queue.ID = :queueID and (t.SiteID = q.ComponentID or t.OriginalSiteID = q.ComponentID)")
    .SetParameter("queueID", queueID).List<Task>().ToList();

List<Task> tasksFromWorkflow = NHibernateSession
    .CreateCriteria(typeof(Task), "Task")
    .CreateCriteria("Task.Order", "Order")
    .CreateAlias("Task.TaskDevice", "TaskDevice").List<Task>();

IEnumerable<Task> tasks = tasksFromWorkflow.Intersect(tasksFromQueue);

如您所见,我有两个问题:

  • 对第一个查询使用详细语法,为第二个查询使用NHibernate标记。
  • 按两次DB然后交叉结果。

tasksFromWorkflow查询实际上比上面看到的要复杂得多。如果您想查看整个查询click here.我不确定额外的代码是否真的改变了我的问题 - 所以我决定尽可能缩短立即显示的代码段,同时仍然解释问题

我读过NHibernate doesn't support intersection,所以也许在一个查询中不可能实现而不会变得非常错综复杂?

1 个答案:

答案 0 :(得分:1)

我不知道这将是多么高效,但这个想法应该是明确的

var tasksFromQueue = DetachedCriteria.For<Task>()
            .Add(Restrictions.Or(
                Subqueries.In("SiteID", DetachedCriteria.For<QueueLocation>().Add(Restrictions.Eq("Queue.ID", queueID)).SetProjection(Projections.Property("ComponentID"))),
                Subqueries.In("OriginalSiteID", DetachedCriteria.For<QueueLocation>().Add(Restrictions.Eq("Queue.ID", queueID)).SetProjection(Projections.Property("ComponentID")))))
            .SetProjection(Projections.Id());

    "Select t from Task t, QueueLocation q where q.Queue.ID = :queueID and (t.SiteID = q.ComponentID or t.OriginalSiteID = q.ComponentID)")
    .SetParameter("queueID", queueID).List<Task>().ToList();

var tasksFromWorkflow = DetachedCriteria.For<Task>()
    .CreateAlias("Order", "order")
    .CreateAlias("TaskDevice", "device")
    .Add(<restrictions>)
    .SetProjection(Projections.Id());

var results = NHibernateSession.CreateCriteria<Task>()
    .Add(Subqueries.In("Id", tasksFromQueue))
    .Add(Subqueries.In("Id", tasksFromWorkflow))
    .List<Task>();