我有一个NHibernate条件,我需要从中获得SQL查询。我从这里尝试了各种方法。然而,我得到的查询中没有参数(它有一个"?"来代替它,就像这里和这里提到的那样)。此外,至少有一件事不起作用,那就是criteria.setMaxResults(n).
我也试过NHibernate拦截弹。但是,我在OnPrepareStatement(sql)中得到的查询也没有参数。有没有其他方法可以从条件中获取sql查询?
附言:-标准是从一开始就创建的,因为它更容易用于复杂的业务需求。然而,我需要进行数据导出,这在标准中非常缓慢。我正在尝试从条件中获取查询,然后从中进行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();
}