【问题标题】:Nhibernate - Using logging for a specific ISession or ISessionFactoryNhibernate - 为特定的 ISession 或 ISessionFactory 使用日志记录
【发布时间】:2013-03-29 08:37:10
【问题描述】:

我们使用的是 NHibernate 3.2。

我希望能够记录来自特定 ISession 的 SQL 查询。这可能吗?

或者,如果这不可能,我可以将记录器设置为特定的 ISessionFactory 吗?然后我可以从这个特定的工厂创建这个 ISession。

据我所见,要设置记录器,您必须执行以下操作:

<appSettings>
       <add key="nhibernate-logger" value="NH3SQLLogger.LoggerFactory, NH3SQLLogger" />
</appSettings>    

但是,这将使所有工厂的设置全局化。

我可以这样做吗:

        var config = new Configuration();
        config.Configure();
        config.SetProperty("nhibernate-logger",
                       "NH3SQLLogger.LoggerFactory, NH3SQLLogger");
        _sessionFactory = config.BuildSessionFactory();

这行得通吗?还是有别的办法?

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    不,您只能在全局范围内指定记录器。做你想做的事会相当复杂。

    您需要:

    1. 编写自己的 ILoggerFactory 实现
    2. 从 NHibernate.SQL 捕获日志数据以捕获所有 SQL
    3. 从 NHibernate.Impl.SessionImpl 捕获日志数据以捕获生成 SQL 的 ISession 和 ISessionFactory。
    4. 对逻辑进行编码以忽略除您命名的 ISessionFactory 生成的 SQL 之外的所有 SQL。

    这里有一些代码可以帮助您入门:

    public class LoggerFactory : ILoggerFactory
    {
        #region Implementation of ILoggerFactory
    
        /// <summary>
        /// Returns the logger for a given key name
        /// </summary>
        /// <param name="keyName">Key or class name</param>
        /// <returns>Logger</returns>
        public IInternalLogger LoggerFor( string keyName )
        {
            if ( string.IsNullOrWhiteSpace( keyName ) )
                return new NoLoggingInternalLogger();
    
            switch ( keyName )
            {
                case "NHibernate.SQL":
                    return new SqlLogger(); // Create this class to capture the SQL
                case "NHibernate.Impl.SessionImpl":
                    return new SessionLogger(); // Create this class to capture ISession-related stuff
                default:
                    return new NoLoggingInternalLogger();
            }
        }
    
        /// <summary>
        /// Returns the logger for a given type
        /// </summary>
        /// <param name="type">Class name</param>
        /// <returns>Logger</returns>
        public IInternalLogger LoggerFor( Type type )
        {
            return LoggerFor( type.FullName );
        }
    
        #endregion Implementation of ILoggerFactory
    }
    

    【讨论】:

    • 感谢您的详细回答,兰迪。然而,我对这个解决方案有点警惕,因为这意味着这个记录器将为系统中的每个会话执行,这将导致全局性能下降。没有其他方法(例如不记录)从特定会话中获取完整的 SQL 吗?
    • 另外,如果你能看看这个,后续问题:stackoverflow.com/questions/15700406/… 谢谢!
    • @VitalyB 不幸的是,我不知道有任何其他方法可以访问完整的 SQL 查询字符串和参数。是的,创建客户 ILoggerFactory 会导致某种性能下降。我也看了你的后续问题,但我没有任何其他贡献,因为我从来没有做过类似的事情。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 2011-07-16
    • 2010-10-09
    • 1970-01-01
    相关资源
    最近更新 更多