簡體   English   中英

在標准執行之前,從NHibernate標准獲取SQL查詢

[英]get SQL query from NHibernate criteria, before the criteria executes

我有一個NHibernate標准,我需要從中獲取SQL查詢。 我從這里嘗試了各種方法。 但是,我得到的查詢中沒有參數(它有一個'?'代替它,就像在這里這里提到的那樣)。 此外,至少有一件不起作用的是criteria.setMaxResults(n)。

我也嘗試過NHibernate攔截器。 但是,我在OnPrepareStatement(sql)中獲得的查詢也沒有參數。 有沒有其他方法從標准獲取SQL查詢?

PS: - 標准是首先創建的,因為它更容易與它們一起工作以滿足復雜的業務需求。 但是,我需要進行數據導出,這通過標准非常慢。 我試圖從標准中獲取查詢,然后從中執行bcp導出。

使用記錄器,在執行代碼之前配置

var sqlLogger = (Logger)LogManager.GetRepository().GetLogger("NHibernate.SQL");
_sqlappender = new NhSqlAppender();
sqlLogger.AddAppender(_sqlappender);
if (!sqlLogger.IsEnabledFor(Level.Debug))
    sqlLogger.Level = Level.Debug;

class NhSqlAppender : AppenderSkeleton
{
    private List<string> queries = new List<string>(1000);

    public IList<string> Queries
    {
        get { return queries; }
    }

    protected override void Append(LoggingEvent loggingEvent)
    {
        queries.Add(loggingEvent.RenderedMessage);
    }
}

如何注入非執行連接

class FakeConnectionFactory : DriverConnectionProvider
{
    public override IDbConnection GetConnection()
    {
        return new FakeConnection(base.GetConnection());
    }
}

class FakeConnection : DbConnection
{
    private IDbConnection _connection;

    public FakeConnection(IDbConnection connection)
    {
        _connection = connection;
    }

    ...

    protected override DbCommand CreateDbCommand()
    {
        return new FakeCommand(_connection.CreateCommand());
    }
}

class FakeCommand : DbCommand
{
    private IDbCommand iDbCommand;

    public FakeCommand(IDbCommand iDbCommand)
    {
        this.iDbCommand = iDbCommand;
    }

    ...

    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
    {
        return EmptyDataReader();
    }

    public override int ExecuteNonQuery()
    {
        return 0;
    }

    public override object ExecuteScalar()
    {
        return 0;
    }
}

為了自己回答這個問題,我認為不可能獲得包含所有參數的完整查詢,因為參數是在所有地方添加的。 此外,還有一些技術也存在其他問題,例如在使用條件連接walker的情況下,setMaxResults不起作用,並且在nhibernate中受到破壞性更改。

我認為這種擴展方法可以滿足您的需求

  public static String ToSql(this ICriteria criteria)
    {
        var criteriaImpl = criteria as CriteriaImpl;
        var sessionImpl = criteriaImpl.Session;
        var factory = sessionImpl.Factory;
        var implementors = factory.GetImplementors(criteriaImpl.EntityOrClassName);
        var loader = new CriteriaLoader(factory.GetEntityPersister(implementors[0]) as IOuterJoinLoadable, factory, criteriaImpl, implementors[0], sessionImpl.EnabledFilters);

        return loader.SqlString.ToString();
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM