在 NHibernate QueryOver 上从 VS2010 迁移到 VS2017 的问题

Problems migrating from VS2010 to VS2017 on NHibernate QueryOver

由于我们已将我们的解决方案从 VS2010 迁移到 VS2017,因此 NHibernate QueryOver 的 lambda 表达式无法正常工作。经过各种测试后,我发现删除 JoinAlias(但从代码中明确删除它是独立的,无论是否执行),代码工作正常。

在调试 NHibernate (3.3.3SP1) 之后,我发现区别在于连接的别名(表达式),在糟糕的情况下它被检测为 MemberAccess,并且对应的字符串很奇怪。

我将尝试展示我的代码的相关部分,但单独测试它工作正常:

LiquidacionDao.cs

Poliza aliasJoinCia = null;
this.Session.QueryOver<Recibo>(() => recibo)
    .Inner.JoinQueryOver<Poliza>(r => r.Poliza, () => aliasJoinCia);
...
...
...
// If I remove those lines, the code works
GestorDeCobro aliasJoinGestoresCobro = null;
queryOver.Inner.JoinAlias(r => r.GestorDeCobro, () => aliasJoinGestoresCobro);
...
...
return queryOver.List();

调试 JoinQueryOver 和 JoinAlias,我已经看到当它工作时(没有最后一行)调试器在手表上显示以下字符串:

{() => value(mpm.seg.Dao.Recibos.Liquidaciones.LiquidacionDao+<>c__DisplayClass33_0).aliasJoinCia}

和 属性 "DebugView":

.Constant<mpm.seg.Dao.Recibos.Liquidaciones.LiquidacionDao+<>c__DisplayClass6_0>(mpm.seg.Dao.Recibos.Liquidaciones.LiquidacionDao+<>c__DisplayClass6_0).aliasJoinCia

当它失败时,手表会显示以下字符串:

{() => value(mpm.seg.Dao.Recibos.Liquidaciones.LiquidacionDao+<>c__DisplayClass33_3).CS$<>8__locals1.aliasJoinCia}

和 属性 "DebugView":

.Lambda #Lambda1<System.Func`1[mpm.seg.ServiceModel.DataContracts.Polizas.Poliza]>() {
    (.Constant<mpm.seg.Dao.Recibos.Liquidaciones.LiquidacionDao+<>c__DisplayClass34_3>(mpm.seg.Dao.Recibos.Liquidaciones.LiquidacionDao+<>c__DisplayClass34_3).CS$<>8__locals1).aliasJoinCia
}

我不明白为什么表达式在某些情况下被解释不同,并且仅在 Visual Studio 2017 年,如果我在 Visual Studio 2010 年打开代码总是可以正常工作。

是时候升级了。

2015 年 Visual Studio 中引入的 Roslyn 编译器对表达式树中闭包的生成方式带来了轻微的变化。不幸的是,这种变化在 NHibernate 中是无法预料的(很难预测这种变化)。

这已在 3.3.5/3.4.1/4.0.4 中修复(问题:NH-3795)。

版本 3.3.5 在您使用的版本之上仅修复了 2 个错误,因此升级应该非常安全。