QueryOver - я думал, что идентификаторы были свободны? - PullRequest
0 голосов
/ 29 октября 2011

Это заняло у меня некоторое время, но я понял, как получить то, что я хочу - в основном.Мой код:

        var sq = QueryOver.Of<VehicleGroup>(() => vehicleGroup)
                    .JoinQueryOver<Manager>(vg => vg.Managers)
                        .Where(man => man.Id == managerId)
                    .JoinQueryOver<TruckPCBase>(() => vehicleGroup.Vehicles)
                        .Where(v => v.Id == item.VehicleId)
                    .Select(vg => vg.Id)
                    ;

        var vp = Session.QueryOver<Summary>(() => item)
            .WithSubquery.WhereExists(sq)
            .Take(10)
            .List();

Это возвращает именно то, что я хочу.

ОДНАКО, мне пришлось сопоставить дополнительное поле, чтобы оно работало.Компонент VehicleBase.Я хотел сделать следующее:

        var sq = QueryOver.Of<VehicleGroup>(() => vehicleGroup)
                    .JoinQueryOver<Manager>(vg => vg.Managers)
                        .Where(man => man.Id == managerId)
                    .JoinQueryOver<TruckPCBase>(() => vehicleGroup.Vehicles)
                        .Where(v => v.Id == item.VehicleBase.Id)
                    .Select(vg => vg.Id)
                    ;

        var vp = Session.QueryOver<Summary>(() => item)
            .WithSubquery.WhereExists(sq)
            .Take(10)
            .List();

Это дает следующую ошибку:

System.NullReferenceException: Object reference not set to an instance of an object.
at lambda_method(ExecutionScope ) 

Хорошо, поэтому я добавил дополнительную выборку:

        var sq = QueryOver.Of<VehicleGroup>(() => vehicleGroup)
                    .JoinQueryOver<Manager>(vg => vg.Managers)
                        .Where(man => man.Id == managerId)
                    .JoinQueryOver<TruckPCBase>(() => vehicleGroup.Vehicles)
                        .Where(v => v.Id == item.VehicleBase.Id)
                    .Select(vg => vg.Id)
                    ;

        var vp = Session.QueryOver<Summary>(() => item)
            .Fetch(sum => sum.VehicleBase).Eager
            .WithSubquery.WhereExists(sq)
            .Take(10)
            .List();

Нетигральная кость.Я не хочу добавлять новое свойство в мой класс Summary (VehicleId) - я хочу получить к нему доступ через Summary.VehicleBase.Id

Предложения?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2011

Получил это на работу !!!

var sq = QueryOver.Of<VehicleGroup>()
    .Inner.JoinAlias(vg => vg.Managers, () => manager)
    .Where(() => manager.Id == managerId)
    .JoinQueryOver(x => x.Vehicles, () => vehicle)
    .Select(x => vehicle.Id)
    ;


var vp = Session.QueryOver<Summary>()
    .Fetch(vpr => vpr.VehicleBase).Eager
    .WithSubquery.WhereProperty(x => x.VehicleBase.Id).In(sq)
    .Take(10)
    .List()
    ;

Это генерирует следующий SQL

SELECT
    TOP (@p0) this_.summaryID as summaryID42_1_,
    ... close to 200 columns cut ...
FROM
    dbo.Summary this_ 
left outer join
    dbo.Vehicle vehiclebas2_ 
        on this_.VehicleID = vehiclepcbas2_.VehicleID 
WHERE
    this_.vehicleID in (
        SELECT
            vehicle2_.vehicleID as y0_ 
        FROM
            dbo.Groups this_0_ 
        inner join
            dbo.Manager_Rel managers4_ 
                on this_0_.groupId=managers4_.groupId 
        inner join
            dbo.Managers manager1_ 
                on managers4_.managerId=manager1_.ManagerId 
        inner join
            dbo.Object_Rel vehicles6_ 
                on this_0_.groupId=vehicles6_.groupId 
        inner join
            dbo.Vehicle vehicle2_ 
                on vehicles6_.ID=vehicle2_.VehicleID 
        WHERE
            this_0_.type=1 
            AND manager1_.ManagerId = @p1
    );
@p0 = 10 [Type: Int32 (0)], @p1 = 34 [Type: Int32 (0)]

Точно (я думаю), что я хотел.

0 голосов
/ 30 октября 2011

Я не мог полностью понять, что вы пытаетесь сделать, но проблема, похоже, в следующем:

вы получаете это исключение, потому что для этой строки

.Where(v => v.Id == item.VehicleBase.Id)

item равно нулю. Анализатор выражений linq для nhibernate будет стараться оценить все, что не включает параметр lambda. Для этого случая:

v.Id => будет оцениваться позже и перейдет на HQL item.VehicleBase.Id => нет зависимости от v, поэтому оценщик с нетерпением его оценит, что приведет к NRE.

...