Sql Nhibernate连接过滤
我有一个关于NHIBERNATE中的连接的问题。我们的sql查询有一个问题,但生成的是nhibernate。我们的db开发人员对原始sql进行了优化,使其能够按照我们的需要工作,但我们需要更改nhibernate代码,使生成的sql看起来像是优化的 查询的原始部分是: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
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());