【问题标题】:get SQL query from NHibernate criteria, before the criteria executes在条件执行之前从 NHibernate 条件获取 SQL 查询
【发布时间】:2012-03-14 11:58:14
【问题描述】:

我有一个 NHibernate 标准,我需要从中获取 SQL 查询。我尝试了here 的各种方法。但是,我得到的查询中没有参数(它有一个“?”代替它,就像在herehere 中提到的那样)。此外,至少有一件事不起作用是criteria.setMaxResults(n)。

我也尝试过 NHibernate 拦截器。但是,我在 OnPrepareStatement(sql) 中获得的查询也没有参数。有没有其他方法可以从条件中获取 sql 查询?

PS:- 标准是首先创建的,因为它更容易使用它们来满足复杂的业务需求。但是,我需要导出数据,这通过标准非常慢。我正在尝试从条件中获取查询,然后从中执行 bcp 导出。

【问题讨论】:

    标签: c# sql nhibernate


    【解决方案1】:

    使用记录器,在执行代码之前配置

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

    【讨论】:

    • 这不会在执行后给我查询,因为它来自日志?我需要条件将触发的查询,以便以其他方式使用它。
    • 这并不容易,因为参数是到处添加的。你可以实现一个不执行的假连接和命令
    • 是否有相同的链接/参考?
    【解决方案2】:

    要自己回答这个问题,我认为不可能获得包含所有参数的完整查询,因为参数是到处添加的。此外,一些技术也存在其他问题,例如在使用条件连接 walker 的情况下,setMaxResults 不起作用,并且会在 nhibernate 中发生重大变化。

    【讨论】:

      【解决方案3】:

      我认为这种扩展方法可以满足您的需求

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-28
        • 2011-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-04
        • 2019-11-18
        相关资源
        最近更新 更多