web-dev-qa-db-fra.com

Comment configurer Fluent NHibernate pour générer des requêtes vers Trace ou Debug au lieu de Console?

Comment configurer Fluent NHibernate pour générer des requêtes vers Trace ou Debug au lieu de Console? J'utilise MsSqlConfiguration.MsSql2008.ShowSql() mais il n'a pas de paramètres et je ne trouve rien sur Google.

51
André Pena

Partout dans le forum et les articles de blog, je peux voir que de nombreuses autres personnes avant moi ont cherché un moyen d'obtenir les instructions SQL en cours de préparation pour l'exécution. La réponse est généralement quelque chose comme "vous ne pouvez pas" ou "vous ne devriez pas".

Que je devrais ou non, c'est ce que je voulais.

Après des heures de recherches, d'enquêtes et de tentatives infructueuses, j'ai finalement trouvé ça.

Écrivez un intercepteur:

using NHibernate;
using System.Diagnostics;

public class SqlStatementInterceptor : EmptyInterceptor
{
    public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
    {
        Trace.WriteLine(sql.ToString());
        return sql;
    }
}

Bien sûr, vous n'avez pas besoin de Trace.WriteLine() ici, vous pouvez l'écrire dans un fichier journal, ou tout ce dont vous avez besoin.

Dans votre gestionnaire de connexions, connectez votre intercepteur comme suit:

protected virtual void Configure(FluentConfiguration config)
{
    config.ExposeConfiguration(x =>
                                   {
                                       x.SetInterceptor(new SqlStatementInterceptor());
                                   });
}

Ce n'est pas si compliqué. De mon point de vue, certainement plus facile que d'essayer de faire passer tout ce XML via Fluent vers NHibernate - puisque Fluent résume le fichier XML.

Gardez à l'esprit que vous ne pouvez avoir qu'un seul intercepteur - vous devrez donc peut-être intégrer cette fonctionnalité à votre intercepteur existant, si vous en avez déjà un. Sur cette note, vous voudrez peut-être lui donner un nom plus large - par exemple MyAppInterceptor, afin de ne pas impliquer un objectif spécifique, car vous souhaiterez peut-être y ajouter d'autres fonctionnalités ultérieurement.

J'espère que cela sera utile à quelqu'un d'autre! :-)

95
mindplay.dk

Vous voulez probablement utiliser log4net, pas ShowSql. Voici une configuration pour envoyer des requêtes à Debug:

  <configSections>
    <section name="log4net"
     type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>

  <log4net debug="false">
    <appender name="WindowsDebugOutput" type="log4net.Appender.DebugAppender,
         log4net">
      <layout type="log4net.Layout.PatternLayout,log4net">
        <param name="ConversionPattern"
              value="%d{ABSOLUTE} %-5p %c{1}:%L - %m%n" />
      </layout>
    </appender>

    <logger name="NHibernate.SQL" additivity="false">
      <level value="DEBUG" />
      <appender-ref ref="WindowsDebugOutput" />
    </logger>
  </log4net>

Et puis appelez cela à partir de votre code avant d'ouvrir une session NHibernate:

log4net.Config.XmlConfigurator.Configure();

Lorsque vous ajoutez une référence à la DLL log4net, assurez-vous de définir sa propriété "Copier local" sur "true".

Ce n'est pas spécifique à FluentNHibernate, cela fonctionne de la même manière dans toutes les variantes de NHibernate.

33
Michael Maddox

Je n'ai pas essayé cela avec SQL Server, mais avec SQLite, le code suivant affichera le SQL généré dans la fenêtre Sortie (menu Déboguer -> Windows -> Sortie, dans VS2008).

La zone de liste déroulante "Afficher la sortie de:" dans la fenêtre Sortie doit être définie sur "Debug" - VS2008 l'a fait automatiquement pour moi.

            sessionFactory = Fluently.Configure()
                .Database(SQLiteConfiguration.Standard
                            .UsingFile(DbFile)
                            // Display generated SQL in Output window
                            .ShowSql()
                          )
                .Mappings(m => m.AutoMappings.Add( GetAutoPersistenceModel() ))
                .BuildSessionFactory()
                ;

Un mot d'avertissement - l'activer peut ralentir considérablement l'exécution.

11
Tom Bushell