2012-05-22 5 views
43

Я знаю, как записывать SQL в log4net/NLog/trace окно во время выполнения с опцией конфигурации show_sql.Как я могу NHibernate генерировать SQL без его выполнения?

Что я ищу - это способ дать Query<T>() NHibernate получить сгенерированный SQL.

Я просмотрел класс Персидер, Драйверы, различные перехватчики и события. Есть так много мест для поиска, даже сужение моего поиска будет очень полезно.

+0

То, что я пытаюсь выполнить профайлер бедняка сортов. Я просто хочу знать, как конкретный запрос linq будет оцениваться из части тестового кода. – hometoast

ответ

84

Вы можете получить сгенерированные SQL запросов без исполнения со следующими методами:

Для запросов NHibernate.Linq:

public String GetGeneratedSql(System.Linq.IQueryable queryable, ISession session) 
{ 
    var sessionImp = (ISessionImplementor) session; 
    var nhLinqExpression = new NhLinqExpression(queryable.Expression, sessionImp.Factory); 
    var translatorFactory = new ASTQueryTranslatorFactory(); 
    var translators = translatorFactory.CreateQueryTranslators(nhLinqExpression, null, false, sessionImp.EnabledFilters, sessionImp.Factory); 

    return translators[0].SQLString; 
} 

Для Criteria запросов:

public String GetGeneratedSql(ICriteria criteria) 
{ 
    var criteriaImpl = (CriteriaImpl) criteria; 
    var sessionImpl = (SessionImpl) criteriaImpl.Session; 
    var factory = (SessionFactoryImpl) sessionImpl.SessionFactory; 
    var implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName); 
    var loader = new CriteriaLoader((IOuterJoinLoadable) factory.GetEntityPersister(implementors[0]), factory, criteriaImpl, implementors[0], sessionImpl.EnabledFilters); 

    return loader.SqlString.ToString(); 
} 

Для Запросы QueryOver:

public String GetGeneratedSql(IQueryOver queryOver) 
{ 
    return GetGeneratedSql(queryOver.UnderlyingCriteria); 
} 

Для HQL запросов:

public String GetGeneratedSql(IQuery query, ISession session) 
{ 
    var sessionImp = (ISessionImplementor)session; 
    var translatorFactory = new ASTQueryTranslatorFactory(); 
    var translators = translatorFactory.CreateQueryTranslators(query.QueryString, null, false, sessionImp.EnabledFilters, sessionImp.Factory); 

    return translators[0].SQLString; 
} 
+0

Есть ли способ сделать это для запросов HQL? –

+0

Обновлен мой ответ с помощью запросов hql. – Gerard

+1

@Gerard Я поддержал ваш очень полезный ответ. Есть ли у вас какие-либо идеи, возможно ли это для INSERT - UPDATE? См. Http://stackoverflow.com/questions/10786934/how-can-i-get-nhibernate-to-give-me-the-sql-it-would-generate-for-an-insert-up Спасибо! –

1

Основываясь на NHibernate версии 3.4 метод для выражения Linq является:

public String GetGeneratedSql(System.Linq.IQueryable queryable, ISession session) 
     { 
     var sessionImp = (ISessionImplementor)session; 
     var nhLinqExpression = new NhLinqExpression(queryable.Expression,    
            sessionImp.Factory); 
     var translatorFactory = new ASTQueryTranslatorFactory(); 
     var translators = translatorFactory.CreateQueryTranslators(nhLinqExpression.Key, nhLinqExpression, null, false, 
                   sessionImp.EnabledFilters, sessionImp.Factory); 

     var sql = translators.First().SQLString; 
     var formamttedSql = FormatStyle.Basic.Formatter.Format(sql); 
     int i = 0; 
     var map = ExpressionParameterVisitor.Visit(queryable.Expression, sessionImp.Factory).ToArray(); 
     formamttedSql = Regex.Replace(formamttedSql, @"\?", m => map[i++].Key.ToString().Replace('"', '\'')); 

     return formamttedSql; 
     } 
+0

Есть ли способ конвертировать строку sql в hql или в запрос? – Franki1986

Смежные вопросы