【问题标题】:NHibernate QueryOver exists any registerNHibernate QueryOver 存在任何寄存器
【发布时间】:2015-08-31 16:10:06
【问题描述】:

我读到的是,实现“存在”的方法是获取第一个匹配条件的寄存器(在 SQL Server 中它将是 SELECT TOP(1)...),但它必须与Oracle 也是,我不太确定在 Oracle 中,使用 rownumber 是否如此有效。此外,它必须是可扩展的,我可以拥有从 2 或 3 个寄存器到 2 或 3 百万...

我目前的解决方案是这样的:

int? result = this.Session
  .QueryOver<Address>()
  .Where(a => a.Customer.Id == customerId && a.IsMain == true)
  .Select(a => a.Id)
  .Take(1)
  .SingleOrDefault<int?>();

return result != null;

这会在 SQL Server 上生成一个 select top (1) 查询,我认为它比计数(特别是大量)更有效,但在 Oracle 中,生成的查询是这样的:

SELECT y0_
FROM (
    SELECT this_.ADD_Id AS y0_
    FROM ADDRESSES this_
    WHERE (
            this_.CUS_Id = 3942425
            AND this_.ADD_ISMAIN = 'AAAAAAAAAA'
            )
    )
WHERE rownum <= 1

我不太确定该查询在 Oracle 上的效率。

有人可以帮助我使用相同的 NHibernate 指令在两种环境中获得最有效的查询吗?我在一些帖子中找到了类似 Any() 方法,但在 QueryOver 上找不到它...

【问题讨论】:

    标签: sql oracle nhibernate queryover


    【解决方案1】:

    您应该做的是检查正确的方言设置。文档的一些链接:

    3.5.1. SQL Dialects

    您应该始终将 dialect 属性设置为数据库的正确 NHibernate.Dialect.Dialect 子类。除非您希望使用本机或序列主键生成或悲观锁定(例如使用 ISession.Lock() 或 IQuery.SetLockMode()),否则这不是绝对必要的。但是,如果您指定方言,NHibernate 将为上面列出的其他一些属性使用合理的默认值,从而节省您手动指定它们的工作......

    因此,对于适当的方言,使用最合适的语法。嗯……被使用了……

    如今 NHibernate 的缺点是:“零新开发”。因此,如果您使用一些较新版本的 Oracle,而最新的方言是 Oracle10gDialect - 您可以(必须)创建自己的,并做一些魔术来改进该语法。可以找到一些创建自定义方言的示例here

    另外,检查其他方言的语法(例如,SQL 2012 基于对 BUILT-IN“标准 SQL”分页的新支持有很大改进 - Implement paging (skip / take) functionality with this query

    【讨论】:

    • 谢谢,我已经为 Oracle 中的某些操作实现了自定义方言,因此扩展它没有问题,但我会首先知道当前解决方案是否足够高效,以避免自定义实现。
    猜你喜欢
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多