QueryOver - 我以为 ID 是免费的?

发布于 2024-12-12 05:57:28 字数 2277 浏览 0 评论 0原文

我花了一段时间,但我想出了如何得到我想要的东西——主要是。 我的代码:

        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();

这正是我想要的。

但是,我必须映射一个附加字段才能使其正常工作。

Summary 对象有一个 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 访问它

It took me a while, but I figured out how to get what I want - mostly.
My code:

        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();

This returns exactly what I want.

HOWEVER, I had to map an additional field to make it work.

The Summary object has a VehicleBase component. What I wanted to do was:

        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();

This gives the following error:

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

Ok, so I added an additional fetch:

        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();

No dice. I don't want to add a new property to my Summary class (VehicleId) - I want to access it through Summary.VehicleBase.Id

Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤千羽 2024-12-19 05:57:28

我无法完全理解您正在尝试执行的操作,但问题似乎是:

您收到此异常是因为此行

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

item 为空。
nhibernate 的 linq 表达式求值器将尝试急切地求值不包含 lambda 参数的所有内容。对于这种情况:

v.Id => 将稍后进行评估并转向 HQL
item.VehicleBase.Id => 不依赖于 v,因此评估器会急切地评估它,这将引发 NRE。

I couldn't fully understand what you are trying to do however the issue appears to be :

you are getting this exception because for this line

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

item is null.
The linq expression evaluator for nhibernate will try to eagerly evaluate everything that doesn't include the lambda parameter. For this case:

v.Id => will be evaluated later and turned to HQL
item.VehicleBase.Id => no dependency to v so evaluator will evaluate it eagerly which will throw an NRE.

半世晨晓 2024-12-19 05:57:28

得到它的工作!

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)]

(我认为)正是我想要的。

Got it to work!!!

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()
    ;

This generates the following 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)]

Exactly (I think) what I wanted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文