2011-09-07 82 views
0

我試圖重現此SQL查詢中NH:NHibernate的QueryOver上多列加入

select vehicle.Id, price.Price 
from vhc.Vehicle vehicle 
    left outer join vhc.VehiclePrice price on vehicle.Id = price.VehicleId 
      and price.VehiclePriceTypeId = 1 

where price.Id is null or price.VehiclePriceTypeId = 1 
order by price.Price 

的重要組成部分,是第二個連接標準。我希望看到所有車輛,不管它們是否有價格,但是如果它們有任何價格,我想選擇類型1的價格。移除第二個加入標準意味着它不包括所有隻有類型2價格的車輛,3等等,那不好。

途徑我已經試過:

  • 添加全局過濾器VehiclePrice對象過濾僅 VehiclePriceType = 1,但把它放在何處,而不是在加入,所以 沒有運氣那裏。

  • 爲類型1的價格添加子查詢,但是,它再次將其應用於Where,而不是Join。

  • 其他連接類型 - 完整,正確...在這裏似乎沒有意義。

這是一個常見的問題,只是還沒有找到解決方案。有什麼想法嗎?

回答

1

只是一個想法:使用2個查詢在一個往返

var vehiclesWithPrice = session.QueryOver<Vehicle>() 
    .JoinQueryOver<VehiclePrice>(vehicle => vehicle.Prices,() => vpricealias) 
    .Where(price => price.VehiclePriceTypeId == 1) 
    .OrderBy(() => vpricealias.Price).Asc 
    .Select(vehicle => vehicle.Id, vehicle => vpricealias.Price) 
    .Future(); 

var vehiclesWithoutPrice = session.QueryOver(() => vehiclealias) 
    .WithSubquery.WhereNotExists(QueryOver.Of<VehiclePrice>() 
     .Where(price => price.Vehicle.Id == vehiclealias.Id) 
     .Where(price => price.VehiclePriceTypeId == 1) 
    ) 
    .Select(vehicle => vehicle.Id, vehicle => 0) 
    .Future(); 

var vehiclesprices = vehiclesWithoutPrice.Concat(vehiclesWithPrice); 
+0

謝謝。將保持這個我的雷達。爲此使用WITH子句提供的HQL。 QueryOver API中是否有等價物? http://nhforge.org/blogs/nhibernate/archive/2009/05/17/nhibernate-2-1-0-hql-with-clause.aspx – Thomas

+0

沒有我知道的 – Firo

2

這是現在可以用QueryOver(我不知道何時,但我嘗試過這樣做的,不能這樣做) 。

var vpAlias = null; 
var prices = session.QueryOver<Vehicle>() 
    .Left.JoinAlias<VehiclePrice>(x => x.VehiclePrice,() => vpAlias, x => x.VehiclePriceTypeId == 1) 
    .Where(() => vpAlias.Id == null || vpAlias.VehiclePriceTypeId == 1) 
    .Select(x => x.Id,() => vpAlias.Price) 
    .ToList(); 

您需要創建在您想加入對多個域的實體的別名,但似乎你可與JoinAliasJoinQueryOver這樣做,他們只是返回不同的實體。

+0

您是否正在運行新的3.3版本?我還沒有在該版本上嘗試過多次連接。 – Thomas

+0

@Thomas它是3.2.0.4000 – Shagglez