Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Nhibernate连接过滤_Sql_Nhibernate_Inner Join_Where Clause - Fatal编程技术网

Sql Nhibernate连接过滤

Sql Nhibernate连接过滤,sql,nhibernate,inner-join,where-clause,Sql,Nhibernate,Inner Join,Where Clause,我有一个关于NHIBERNATE中的连接的问题。我们的sql查询有一个问题,但生成的是nhibernate。我们的db开发人员对原始sql进行了优化,使其能够按照我们的需要工作,但我们需要更改nhibernate代码,使生成的sql看起来像是优化的 查询的原始部分是: FROM PERSON_VISIT this_ inner join PERSON_Basic per2_ on this_.PERSON

我有一个关于NHIBERNATE中的连接的问题。我们的sql查询有一个问题,但生成的是nhibernate。我们的db开发人员对原始sql进行了优化,使其能够按照我们的需要工作,但我们需要更改nhibernate代码,使生成的sql看起来像是优化的

查询的原始部分是:

FROM   PERSON_VISIT this_
                     inner join PERSON_Basic per2_
                       on this_.PERSON_ID = per2_.PERSON_ID
                     left outer join PERSONC_QUESTIONS perint10_
                       on per2_.PERSON_ID = perint10_.PERSON_ID
                     left outer join TELEPHONE_QUESTIONS intaudit13_
                       on perint10_.PP_QUESTIONS_ID = intaudit13_.PP_QUESTIONS_ID
                     inner join C_QUESTIONS intdef14_
                       on perint10_.QUESTION_ID = intdef14_.QUESTION_ID
                          and perint10_.QUESTIONS_CODE = intdef14_.QUESTIONS_CODE
                          and perint10_.QUESTION_ID = intdef14_.QUESTION_ID
优化的方法是:

FROM   PERSON_VISIT this_
                     inner join PERSON_Basic per2_
                       on this_.PERSON_ID = per2_.PERSON_ID
                     left outer join PERSONC_QUESTIONS perint10_
                       on per2_.PERSON_ID = perint10_.PERSON_ID
                     left outer join TELEPHONE_QUESTIONS intaudit13_
                       on perint10_.PP_QUESTIONS_ID = intaudit13_.PP_QUESTIONS_ID
                     left outer join C_QUESTIONS intdef14_
                       on perint10_.QUESTION_ID = intdef14_.QUESTION_ID
                          and perint10_.QUESTIONS_CODE = intdef14_.QUESTIONS_CODE
                          and perint10_.QUESTION_ID = intdef14_.QUESTION_ID
                          and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE
要将查询从内部联接更改为左外部联接很容易,我只更改了一行代码:

        .CreateAlias("PersonInt.QuestionEntity", "IntDef", JoinType.LeftOuterJoin)
但我怎么能补充呢

                          and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE
使用nhibernate代码

有一个选项可以将PERSON_访问定义中的引用添加到C_问题中,但问题是 PERSON_VISIT到处都在使用,我不希望这个更改可能破坏其他查询,我只想添加一行要添加的代码,我如何才能做到这一点?是否有任何方法可以访问原始联接来更改它?或者以其他方式添加此项

                          and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE
问什么? 我知道有人会说,我们可以通过criteria.add向查询添加限制,但这不是一个选项,因为db developer优化了我们的查询,将此限制从WHERE子句添加到join


如何在不更改模型定义的情况下快速完成此操作?只更改这一个查询而不更改整个模型?

可以使用HQL和标准API

这个问题给了你答案:

这样的事情可能会解决你的问题

.CreateAlias("PersonInt.QuestionEntity", "IntDef", JoinType.LeftOuterJoin, 
      Restrictions.EqProperty("DISCIPLINE_CODE", "IntDef.DISCIPLINE_CODE"))

谢谢你的回答。我们在项目中使用了NHibernate的2.0版本,因此我们没有机会使用带有限制的.CreateAlias的新方法

我已使用拦截器修复了一个问题:

public class SqlInterceptor : EmptyInterceptor, IInterceptor
{
    SqlString IInterceptor.OnPrepareStatement(SqlString sql)
    {
        //manipulating with the sql

        return sql;
    }
}


使用我的查询,不做任何更改。

这个答案很好。问题是我们使用的是nHibernate的2.0.0.4版本,我不可能使用这种方法,而且项目太大,无法在不测试所有代码的情况下更改版本,我们需要快速解决这个问题。也许你知道我如何在2.0.0.4中做到这一点?是否有可能操纵nHibernate生成的原始sql?因为另一个唯一的解决方案是使用sql重写方法。为了使执行计划正常工作,您可以移动额外的join子句并将其添加到WHERE子句中。希望SQL server足够聪明,能够在内部计划中从何处推广到加入,或者为您提供所需的优化计划
.Add(Restrictions.EqProperty(“规程代码”、“IntDef.规程代码”))
正如我前面所说,这是我们在where子句中使用.Add(Restrictions.EqProperty(“规程代码”、“IntDef.规程代码”)时的性能问题。不知道为什么,但在join中使用此限制比在where子句中工作得快得多。快两倍。我已经通过编写拦截器和使用原始sql操作解决了这个问题。谢谢。对不起,我帮不上什么忙了=(
        var factory = Session.SessionFactory;
        var session = factory.OpenSession(new SqlInterceptor());