这是我编写的更复杂的HQL查询之一。我仍然对这个容量的HQL很新,可以使用一些反馈。
我在本机sql中要做的一件事就是将日期comarison东西改成单个查询作为表格,即
FROM
(
SELECT MIN, MAX
FROM ..
) T
以下是方法:
public IList<Order> GetOrdersBy(string referenceNumber = null, int? customerId = null, int? carrierId = null, DateTime? startDate = null,
DateTime? endDate = null, int? websiteId = null, OrderStatus? status = null)
{
var byStatusHql =
@"
select odor
from Order odor
join fetch odor._orderStatusLog statusLog
where
(:referenceNumber is null or odor.Quote.ReferenceNumber=:referenceNumber) and
(:customerId is null or odor.Quote.Customer.CustomerID=:customerId) and
(:carrierId is null or odor.Quote.Carrier.CarrierID=:carrierId) and
(:websiteId is null or odor.Quote.Customer.Website.WebsiteID=:websiteId) and
(
:startDate is null or :startDate >
(select min(CreatedDate) from OrderStatusLog lg where lg in elements(odor._orderStatusLog))
) and
(
:endDate is null or :endDate <=
(select max(CreatedDate) from OrderStatusLog lg where lg in elements(odor._orderStatusLog))
) and
(
:status is null or :status =
(
select Status from OrderStatusLog lg where lg in elements(odor._orderStatusLog)
and lg.OrderStatusLogID = (select max(OrderStatusLogID) from OrderStatusLog lgg where lgg in elements(odor._orderStatusLog))
)
)
";
var query = Session.CreateQuery(byStatusHql);
query.SetParameter("referenceNumber", referenceNumber)
.SetParameter("customerId", customerId)
.SetParameter("carrierId", carrierId)
.SetParameter("websiteId", websiteId)
.SetParameter("startDate", startDate)
.SetParameter("endDate", endDate)
.SetParameter("status", status)
;
return query.List<Order>();
}
答案 0 :(得分:0)
您的意思是“优化”在性能或可读性方面吗?
考虑到性能,我会使用Criteria或QueryOver来仅添加实际使用的过滤器参数。标准不是那么强大,在这种情况下语法会更复杂,但动态组合查询更容易。
您可以尝试在日志中使用单个子查询来聚合:
and exists (
select min(CreatedDate), max(CreatedDate), max(OrderStatusLogID)
from OrderStatusLog lg
where lg in elements(odor._orderStatusLog)
having
:startDate is null or :startDate > min(CreatedDate)
and :endDate is null or :endDate <= max(CreatedDate)
and :status is null or :status = (
select lgg.Status from OrderStatusLog lgg
where lgg.id = max(OrderStatusLogID)))
我不知道这一切是否奏效。带状态的最后一个对于having子句来说可能太多了。
但是,它执行得不是很好,因为当参数为null时,可以省略子查询。我怀疑DBMS是否足够智能以优化它。