我试图在NH中重现这个SQL查询:
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但它将它放在Where上,而不是在Join上,所以 那里没有运气。
为类型为1的价格添加SubQuery,但同样,它会将其应用于Where,而不是Join。
其他联接类型 - Full,Right ......这里似乎没有意义。
这是一个常见问题,尚未找到解决方案。有什么想法吗?
答案 0 :(得分: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();
您需要为要在多个字段上加入的实体创建别名,但似乎您可以使用JoinAlias
或JoinQueryOver
来实现,只需返回不同的实体
答案 1 :(得分: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);