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



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

在存储库由NHibernate(顺便说一句,3.1)支持的情况下,简单谓词(如x => x.Name="Mike")可以通过LINQ for NHibernaate(使用Where(Expression<Func<T, bool>>)方法)"向下推"到关系数据库,当底层实体集很大并且谓词只选择一个实体时,性能会明显提高。美好的

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

问题是,我无法找到可靠的方法来检测LINQ to NHibernate未能翻译谓词表达式。直接执行查询会抛出系统。NotSupportedException,这可能是由任何原因引起的,甚至是由底层的ConnectionProvider引起的。

我考虑了一下将查询执行一分为二的可能性——先翻译,然后执行——然后捕获系统。翻译过程中出现NotSupportedException。为此,我尝试了在中提出的解决方案。有人知道如何将LINQ表达式翻译为NHibernate HQL语句吗?为了在执行前翻译查询,我不得不说,我让它工作了,但它使用反射来访问内部NHibernate对象的未记录的、非公共的方法,因此它闻起来像是一个不受支持的黑客。

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

我不认为有,但由于NHibernate是一个开源项目,你可以很容易地这样做:

  1. 获取NHibernate的源代码
  2. 用更具体的异常替换LINQ提供程序中的所有NotSupportedException(它将继承NotSupportedException以避免不必要的中断)
  3. 编译修改后的NHibernate并在代码中使用它
  4. 在代码中需要新异常的任何地方/以任何方式处理它
  5. 将您的修改作为补丁提交给NHibernate JIRA(不要忘记测试,否则可能不会考虑)
  6. 利润

相关内容

  • 没有找到相关文章

最新更新