我正在尝试编写一个 NHibernate 查询来确定指定的记录是否与请求的来源相关。在这种情况下,指定的记录是客户,如果客户有任何来自指定来源的订单,则该客户是相关的。
我已经尝试过了,但以下查询失败并显示QuerySyntaxException
.
bool IsRelevant = Session.Query<Order>().Where
(
ThisOrder => ThisOrder.Customer.ID == ThisCustomer.ID
&&
ThisOrder.Items.OfType<SourceOrderItem>().Where
(
I => I.Source.ID == Source.ID
).Count() > 0
).Count() > 0;
我认为问题的至少一部分是它SourceOrderItem
的子类型,OrderItem
并且订单可能包含不属于该类型的项目,因此查询需要额外的过滤以仅查看类型正确的项目。
例外:
Exception of type 'Antlr.Runtime.NoViableAltException' was thrown. [.Count[Domain.Order](.Where[Domain.Order](NHibernate.Linq.NhQueryable`1[Domain.Order], Quote((R, ) => (AndAlso(Equal(R.Customer.ID, p1), GreaterThan(.Count[Domain.SourceOrderItem](.Where[Domain.SourceOrderItem](.OfType[Domain.SourceOrderItem](R.Items, ), (I, ) => (Equal(I.Source.ID, p2)), ), ), p3)))), ), )]
使用 Nhibernate 版本 3.1.0.4000
将 this 更改为使用Any
而不是Where().Count > 0
导致尝试运行查询的 SQL 异常
DECLARE @p0 int
DECLARE @p1 int
DECLARE @p2 int
SET @p0 = 1
SET @p1 = 1
SET @p2 = 1
select TOP (@p0)
request0_.ID as ID24_,
request0_.Date as Date24_,
request0_.Delivery as Delivery24_,
request0_.PO as PO24_,
request0_.Discount as Discount24_,
request0_.Notes as Notes24_,
request0_.PaymentType as PaymentT7_24_,
request0_.Transport as Transport24_,
request0_.Customer_id as Customer9_24_,
request0_.Site_id as Site10_24_,
request0_.CreatedBy_id as CreatedBy11_24_,
request0_1_.OrderNumber as OrderNum2_25_,
request0_2_.Revision as Revision26_,
request0_2_.ExpiryDate as ExpiryDate26_,
case
when request0_1_.Request_id is not null then 1
when request0_2_.Request_id is not null then 2
when request0_.ID is not null then 0
end as clazz_
from [Request] request0_
left outer join [Order] request0_1_ on request0_.ID=request0_1_.Request_id
left outer join [Quote] request0_2_ on request0_.ID=request0_2_.Request_id
where
request0_.Site_id=@p1
and
(exists
(select
items1_.ID
from
[RequestItem] items1_
where request0_.ID=items1_.Request_id
and case
when items1_2_.ChargeableRequestItem_id is not null then 2
when items1_3_.ChargeableRequestItem_id is not null then 3
when items1_1_.RequestItem_id is not null then 1
when items1_4_.RequestItem_id is not null then 4
when items1_.ID is not null then 0
end=3
and items1_3_.Source_id=@p2))
这似乎从语句中丢失了很多,因为没有声明第二个 case 语句下面的表。
现在我已经通过自己编写 SQL 来解决这个问题。
bool IsRelevant = ((Int32)Session.CreateSQLQuery(
"Select COUNT(*) as IsRelevant From Request\r\n" +
"Where\r\n" +
" Request.Site_Id = :p0\r\n" +
" And Request.ID in \r\n" +
"(\r\n" +
"Select Request_ID From RequestItem Where ID in\r\n" +
" ( \r\n" +
" Select SourceOrderItem.ChargeableRequestItem_id\r\n" +
" From SourceOrderItem\r\n" +
" Where SourceOrderItem.Source_id = :p1\r\n" +
" )\r\n" +
")"
).SetParameter("p0", S.ID).SetParameter("p1", Source.ID).UniqueResult()) > 0;
虽然我仍然更喜欢 NHibernate 解决方案。