Configuring NHibernate with App.config

NHibernate offers several methods for configuration and a number of configuration settings.

In this recipe, I'll show you how to configure NHibernate using your application's configuration file with a minimal number of settings to get your application up and running quickly. This recipe also forms the base for several other recipes in this chapter.

Getting ready

  1. Complete the Eg.Core model and mapping recipes from Chapter 1, Models and Mappings.
  2. Add a console application project to your solution called ConfigByAppConfig.
  3. Set it as the Startup project for your solution.
  4. In the ConfigByAppconfig project, add references to NHibernate.dll and NHibernate.ByteCode.Castle.dll from the Lib folder.
  5. In ConfigByAppconfig, add a reference to the Eg.Core project.
  6. Add an App.config file to your console project.

How to do it...

  1. Open the App.config file.
  2. Declare a section for the NHibernate configuration, as shown here:
      <configSections>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
      </configSections>
  3. Add a connectionStrings section with a connection string:
      <connectionStrings>
        <add name="db" connectionString="Server=.SQLExpress; Database=NHCookbook; Trusted_Connection=SSPI"/>
      </connectionStrings>
  4. Add your hibernate-configuration section:
    <hibernate-configuration 
    xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
        <property name="proxyfactory.factory_class">
        NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
      </property>
      <property name="dialect">
      NHibernate.Dialect.MsSql2008Dialect, NHibernate
        </property>
      <property name="connection.connection_string_name">
      db
        </property>
      <property name="adonet.batch_size">
      100
        </property>
      <mapping assembly="Eg.Core"/>
    </session-factory>
    </hibernate-configuration>>
  5. Your completed App.config file should look like this:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      
      <configSections>
        <section name="hibernate-configuration"
           type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
      </configSections>
       <connectionStrings>
        <add name="db" connectionString="Server=.SQLExpress; Database=NHCookbook; Trusted_Connection=SSPI"/>
      </connectionStrings>
       <hibernate-configuration 
        xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
          <property name="proxyfactory.factory_class">
            NHibernate.ByteCode.Castle.ProxyFactoryFactory, 
            NHibernate.ByteCode.Castle
          </property>
          <property name="dialect">
            NHibernate.Dialect.MsSql2008Dialect, 
            NHibernate
          </property>
          <property name="connection.connection_string_name">
            db
          </property>
          <property name="adonet.batch_size">
            100
          </property>
          <mapping assembly="Eg.Core"/>
        </session-factory>
      </hibernate-configuration>
    </configuration>
  6. Open Program.cs and add using NHibernate.Cfg; to the beginning of the file.
  7. In your Main function, add the following code to configure NHibernate:
    var nhConfig = new Configuration().Configure();
    var sessionFactory = nhConfig.BuildSessionFactory();
    Console.WriteLine("NHibernate Configured!");
    Console.ReadKey();
  8. Build and run your application. You will see the text NHibernate Configured!.

How it works...

The connection string we've defined points to the NHCookbook database running under the local Microsoft SQL Server Express 2008.

Next, we define a few properties that tell NHibernate how to behave. proxyfactory.factory_class specifies the proxy framework we'll use. In this case, we're using Castle's DynamicProxy2. Out of the box, NHibernate also supports the LinFu and Spring frameworks.

The dialect property specifies a dialect class that NHibernate uses to build SQL syntax specific to a Relational Database Management System (RDBMS). We're using the Microsoft SQL 2008 dialect. Additionally, most dialects set intelligent defaults for other NHibernate properties, such as connection.driver_class.

The connection.connection_string_name property references our connection string named db. We can name the connection string anything we like, as long as this property matches the connection string's name.

By default, NHibernate will send a single SQL statement and wait for a response from the database. When we set the adonet.batch_size property to 100, NHibernate will group up to 100 SQL INSERT, UPDATE, and DELETE statements in a single ADO.NET command and send the whole batch at once. In effect, the work of 100 round trips to the database is combined in one. Because a roundtrip to the database is, at best, an out-of-process call, and at worst, a trip through the network or even the Internet, this improves performance significantly. Batching is currently supported when using the SqlClientDriver for Microsoft SQL Server or the OracleDataClientDriver for Oracle.

The mappings element defines where NHibernate will search for our mappings. In this case, it will search the Eg.Core assembly for embedded resources ending in .hbm.xml.

There's more...

There are several key components to an NHibernate application, as shown in this diagram:

There's more...

On startup, an NHibernate application builds a Configuration object. In this recipe, we build the configuration from settings in the App.config file. The Configuration object is responsible for loading mappings, reflecting the model for additional information, building the mapping metadata, and finally building a session factory. Building the session factory is an expensive operation, and should be done only once in the life of an application.

The session factory is responsible for building sessions. Unlike a session factory, building a session is very cheap.

A session represents a unit of work in the application. Martin Fowler defines a unit of work as an object that maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems. An NHibernate session tracks changes to entities and writes those changes back to the database all at once. In NHibernate, this process of waiting to write to the database all at once is called transactional write-behind. In addition, the session is the entry point to much of the NHibernate API. More information about the unit of work pattern is available at http://martinfowler.com/eaaCatalog/unitOfWork.html and in Fowler's book, Patterns of Enterprise Application Architecture.

The session acts as an intermediary between our application and several key NHibernate components. A typical application will not interact with these components directly, but understanding them is critical to understanding NHibernate.

A dialect is used to build SQL syntax for a specific RDBMS. For example, in Microsoft SQL Server, we begin a select statement with SELECT TOP 20 to specify a maximum result set size. Only 20 rows will be returned. To do the same in SQLite, we append LIMIT 20 to the end of the select statement. Each dialect provides the necessary SQL syntax string fragments and other information to build correct SQL strings for the chosen RDBMS.

The driver is responsible for building the batcher, creating IDbConnection and IDbCommand objects, and preparing those commands.

The connection provider is simply responsible for opening and closing database connections.

The batcher manages the batch of commands to be sent to the database and the resulting data readers. Currently, only the SqlClientDriver and OracleDataDriver support batching. Those drivers that don't support batching provide a NonBatchingBatcher to manage IDbCommands and IDataReaders and simulate the existence of a single logical batch of commands.

NHibernate properties

Here are some of the commonly used NHibernate properties:

Property name

Description

connection.provider

Provider class to open and close database connections.

connection.driver_class

This is specific to the RDBMS used, and is typically set by the dialect.

connection.connection_string

Database connection string.

connection.connection_string_name

Name of connection string in <connectionStrings> element.

connection.isolation

Transaction isolation level.

dialect

Required. A class to build RDBMS-specific SQL strings. Typically, this is one of the many dialects from the NHibernate.Dialect namespace.

show_sql

Boolean value. Set to true to log all SQL statements to Console.Out. Alternatively, log4net may be used to log to other locations.

current_session_context_class

Class to manage contextual sessions. This is covered in depth in Chapter 3.

query.substitutions

Comma-separated list of translations to perform on query strings. For example, True=1, Yes=1, False=0, No=0.

sql_exception_converter

Class to convert RDBMS-specific ADO.NET Exceptions to custom exceptions.

prepare_sql

Boolean value. Prepares SQL statements and caches the execution plan for the duration of the database connection.

command_timeout

Number of seconds to wait for a SQL command to complete before timing out.

adonet.batch_size

Number of SQL commands to send at once before waiting for a response from the database.

generate_statistics

Enables tracking of some statistical information, such as the number of queries executed and entities loaded.

proxyfactory.factory_class

Required. Specifies a factory class for our chosen proxy framework, in this case Castle DynamicProxy2.

format_sql

Adds line endings for easier-to-read SQL statements.

Additional information about each of these settings is available in the reference documentation at http://www.nhforge.org/doc/nh/en/index.html.

Dialects and drivers

Many dialects set other NHibernate properties to sensible default values, including, in most cases, the connection.driver_class. NHibernate includes the following dialects in the NHibernate.Dialect namespace and drivers in the NHibernate.Driver namespace:

RDBMS

Dialect(s)

Driver(s)

Microsoft SQL Server

MsSql2008Dialect

MsSql2005Dialect

MsSql2000Dialect

MsSql7Dialect

MsSqlCEDialect

SqlClientDriver

SqlServerCEDriver

Oracle

Oracle10gDialect

Oracle9iDialect

Oracle8iDialect

OracleLiteDialect

OracleClientDriver

OracleDataClientDriver

OracleLiteDataDriver

MySql

MySQLDialect

MySQL5Dialect

MySqlDataDriver

PostgreSQL

PostGreSQLDialect

PostGreSQL81Dialect

PostGreSQL82Dialect

NpgsqlDriver

DB2

DB2Dialect

Db2400Dialect

DB2Driver

DB2400Driver

Informix

InformixDialect

InformixDialect0940

InformixDialect1000

IfxDriver

Sybase

SybaseDialect

SybaseASA10Dialect

SybaseASA9Dialect

Sybase11Dialect

SybaseAdoNet12Dialect

SybaseAnywhereDialect

SybaseClientDriver

ASAClientDriver

ASA10ClientDriver

SybaseAdoNet12ClientDriver

Firebird

FirebirdDialect

FirebirdDriver

FirebirdClientDriver

SQLite

SQLiteDialect

SQLiteDriver SQLite20Driver

Ingres

IngresDialect

IngresDriver

See also

  • Configuring NHibernate with hibernate.cfg.xml
  • Configuring NHibernate with code
  • Configuring NHibernate with Fluent NHibernate
  • Configuring NHibernate using ConfORM Mappings
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset