LINQ to NHibernate - 如何检测失败的翻译

Posted

技术标签:

【中文标题】LINQ to NHibernate - 如何检测失败的翻译【英文标题】:LINQ to NHibernate - How to detect failed translation 【发布时间】:2011-06-09 12:33:07 【问题描述】:

我正在编写一个(又一个)通用实体存储库,它不一定由关系数据库支持。我希望IEnumerable<T> Load<T>(...) 方法之一将通用Expression<Func<T, bool>> 谓词作为参数,该谓词指定要检索的实体的用户定义标准。请注意,我不想向用户公开完整的IQueryable<T>,因为我想限制向我的用户公开底层存储。

在存储库由 NHibernate(顺便说一下,3.1)支持的情况下,简单的谓词(例如 x => x.Name="Mike")可以通过 NHibernate 的 LINQ“下推”到关系数据库(使用 @987654326 @ 方法),当基础实体集很大并且谓词仅选择一个实体时,具有明显的性能提升。好的。

但是,我的用户不一定知道存储库由关系数据库支持,因此谓词有时可能非常复杂(例如 x => MyFunction(x.Name) == 0),以至于 LINQ to NHibernate 无法为他们生成 HQL。在这些情况下,我想检测 LINQ 无法生成 HQL 并透明地“故障转移”以加载所有实体并将谓词显式应用于每个实体。

问题是我找不到可靠检测 LINQ to NHibernate 无法转换谓词表达式的方法。立即执行查询会引发 System.NotSupportedException,这可能是由任何原因引起的,甚至是由底层 ConnectionProvider 引起的。

我暂时考虑了将查询执行分成两部分的可能性 - 首先翻译,然后执行 - 然后在翻译期间捕获 System.NotSupportedException。为此,我尝试了Does anyone know how to translate LINQ Expression to NHibernate HQL statement? 中提出的解决方案,以便在执行前翻译查询,我不得不说我让它工作了,但是它使用反射来访问内部 NHibernate 对象的未记录的、非公共的方法,因此它闻起来像不受支持的黑客攻击。

是否有更可靠和“官方”的方法来检测 LINQ to NHibernate 无法翻译表达式,或者在不执行查询的情况下翻译表达式?

【问题讨论】:

【参考方案1】:

我认为没有,但由于 NHibernate 是一个开源项目,您可以像这样轻松地做到这一点:

    抢NHibernate's source code。 将 LINQ 提供程序中的所有 NotSupportedException 替换为更具体的异常(将继承 NotSupportedException 以避免不必要的中断) 编译您修改后的 NHibernate 并在您的代码中使用它。 在您的代码中随时随地处理新的异常。 将您的修改作为补丁提交到NHibernate JIRA(不要忘记测试,否则可能不会被考虑) 利润!

【讨论】:

以上是关于LINQ to NHibernate - 如何检测失败的翻译的主要内容,如果未能解决你的问题,请参考以下文章

用 LINQ to SQL 或 LINQ to EF 替换 NHibernate

对于不支持子查询的 NHibernate-to-LINQ 是不是有任何解决方法?

NHibernate 或 LINQ to SQL [关闭]

有利于启动; Linq to SQL 还是 Nhibernate?

Linq To Nhibernate 性能优化(入门级)

Linq to NHibernate ThenFetch 多个属性