Nhibernate QueryOver объединяет несколько столбцов - PullRequest
0 голосов
/ 07 сентября 2011

Я пытаюсь воспроизвести этот SQL-запрос в NH:

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, но, опять же, он применяет его в месте, а не в соединении.

  • Другие типы соединения - полное, правильное ... здесь, кажется, нет смысла.

Это обычная проблема, но пока не нашли решения. Есть мысли?

Ответы [ 2 ]

2 голосов
/ 03 мая 2012

Теперь это возможно с 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 голос
/ 07 сентября 2011

просто идея: использовать 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);
...