2012-05-22 31 views
43

Tôi biết cách đăng nhập SQL vào cửa sổ log4net/NLog/trace khi chạy với tùy chọn cấu hình show_sql.Làm thế nào tôi có thể có NHibernate chỉ tạo ra các SQL mà không thực hiện nó?

Điều tôi đang tìm kiếm là cách để cung cấp số Query<T>() cho NHibernate truy xuất SQL được tạo.

Tôi đã xem qua lớp Persister, Trình điều khiển, Trình chặn và Sự kiện khác nhau. Có rất nhiều nơi để xem xét, thậm chí thu hẹp tìm kiếm của tôi sẽ giúp ích rất nhiều.

+0

Những gì tôi đang cố gắng để đạt được là profiler một người đàn ông nghèo của các loại. Tôi chỉ muốn biết một truy vấn LINQ cụ thể sẽ đánh giá như thế nào từ một đoạn mã thử nghiệm. – hometoast

Trả lời

84

Bạn có thể nhận các truy vấn sql tạo ra mà không thực hiện với các phương pháp sau:

Đối với các truy vấn 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; 
} 

Đối với Tiêu chuẩn truy vấn:

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 Truy vấnTruy vấn truy vấn:

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

Đối với HQL truy vấn:

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

Có cách nào để làm điều đó cho các truy vấn HQL không? –

+0

Cập nhật câu trả lời của tôi với các truy vấn hql. – Gerard

+1

@Gerard Tôi đã upvoted câu trả lời rất hữu ích của bạn. Bạn có bất kỳ ý tưởng nếu điều này là có thể cho INSERTs - UPDATEs? Xem http://stackoverflow.com/questions/10786934/how-can-i-get-nhibernate-to-give-me-the-sql-it-would-generate-for-an-insert-up Cảm ơn bạn! –

1

Dựa trên phiên bản NHibernate 3.4 phương pháp cho biểu LINQ là:

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

Có cách nào để chuyển đổi chuỗi sql thành hql hoặc truy vấn không? – Franki1986

Các vấn đề liên quan