NHibernate:无法从 IronPython 调用 QueryOver<T>().List()

NHibernate: cannot call QueryOver<T>().List() from IronPython

我正在开发一个使用 NHibernate 和 IronPython 的项目。

所以在 IronPython 中,我可以很好地查询 class Foo 的单个实例。当我想要来自 C# 的 class Foo 的所有实例的列表时,我会做

session.QueryOver<Foo>().List()

但是当我尝试将其翻译成 python 时,

session.QueryOver[Foo]().List()

我总是遇到异常

System.MissingMemberException: 'QueryOver[Foo, Foo]' object has no attribute 'List'

起初我以为 QueryOver 的默认参数有问题,但 ISession 实际上有 4 个重载 QueryOver - none 其中有默认参数-parameters(我仍然尝试像之前的 Can I use Named and Optional Arguments in ironpython 一样传递 Missing.Value,但没有帮助)

然后我认为 List() 可能是一种扩展方法,但我尝试了 clr.ImportExtensions 就像在 https://www.grasshopper3d.com/forum/topics/accessing-my-extension-methods-from-python-component 中一样,但什么也没做。

QueryOver[Foo,Foo] 派生自 QueryOver[Foo]。现在查看 https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Criterion/QueryOver.cs#L223 我发现 QueryOver<Foo> 确实有一个方法 List(),但它的定义方式很奇怪。

我认为该方法只是明确说明了它实现的接口中的哪个 List() 方法,所以我完全不明白这里发生了什么。

有人可以阐明这个问题吗?我越来越绝望了。

我想通了:

https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Criterion/QueryOver.cs#L223 is an explicitly implemented interface-method. According to https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/explicit-interface-implementation 中的 "weird" 定义这样的方法实际上并没有成为对象的成员(恕我直言,这是非常违反直觉的——你有一个实现接口的对象,但后来没有没有来自该接口的方法!?)。这就是 IronPython 找不到方法的原因 - C# 显然以不同方式解析调用。

无论如何 - 根据 http://www.voidspace.org.uk/ironpython/dark-corners.shtml#interfaces,您需要在 python 中以不同方式调用此类方法。您需要显式 select 您使用的接口,如下所示:

IQueryOver[Foo].List(session.QueryOver[Foo]())

老实说,我不明白为什么这个问题会被否决。恕我直言,这是一个相对合理的用例(考虑到 NHibernate 和 IronPython 都是流行的库)并且恕我直言,令人惊讶的是它不像我第一次尝试的那样工作。 在提出问题之前,我自己尝试了几种方法来解决问题 - 为了最终解决它,我不得不通过 NHibernate 源代码,猜测该定义的作用(因为它相当奇特并且没有很好地记录恕我直言)然后找到你可以得到的方法python 来处理它应该能够自己处理的情况。