2012-05-22 12 views
43

show_sql yapılandırma seçeneğiyle çalışma zamanında SQL log4net/NLog/trace penceresinin nasıl kaydedileceğini biliyorum.NHibernate'in yalnızca SQL'i çalıştırmadan nasıl oluşturabilirim?

Aradığım şey, oluşturulan SQL'e NHibernate için Query<T>() vermenin bir yoludur.

Persister sınıfını, Sürücüleri, farklı Interceptors ve Olayları inceledim. Aramak için çok fazla yer var, hatta aramamı daraltıyor olsa da büyük bir yardım olurdu.

+0

türlü kötü adamın profiler olduğunu. Sadece belirli bir linq sorgusunun bir test kodundan nasıl değerlendirileceğini bilmek istiyorum. – hometoast

cevap

84

yapabilirsiniz aşağıdaki yöntemlerle yürütmesi olmadan oluşturulan sql sorguları olsun: Kriterler sorgular için

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; 
} 

:

NHibernate.Linq sorgular için

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(); 
} 

için Sorgu Sorguları:

HQL için 0
public String GetGeneratedSql(IQueryOver queryOver) 
{ 
    return GetGeneratedSql(queryOver.UnderlyingCriteria); 
} 

sorgular: linq ifadesi için NHibernate sürüm 3.4 yöntemi dayanarak

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 sorguları için bunu yapmanın bir yolu var mı? –

+0

Cevabım, hql sorguları ile güncellendi. – Gerard

+1

@Gerard Çok yararlı cevabınızı destekledim. INSERTs - UPDATEs için bunun mümkün olup olmadığı hakkında bir fikriniz var mı? Http://stackoverflow.com/questions/10786934/how-can-i-get-nhibernate-to-give-me-the-sql-it-would-generate-for-an-insert-up adresine bakın. Teşekkür ederiz! –

1

: Ben başarmak çalıştığım şey

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

'da 'CreateQueryTranslators' yeni imzası için NHibernate.Linq sorguları yöntemini düzenledi sql dizesini hql veya queryover'e dönüştürmenin bir yolu var mı? – Franki1986