views:

242

answers:

0

How might I use a stored procedure from NHibernate but at the same time keep the solution database-agnostic and the codebase clean of switch statements with a case for each Dialect?

I expect to create a Named Query per database implementation containing the content of the database-specific sql implementation of the procedure. My dilemma is how best to conditionally invoke the correct named query. Specifically we're testing against both MySQL and MS SQL Server 2008 dialects at the moment.

Does anyone know how to create a conditional named query map by dialect? (This would allow the various stored procedure implementations to be stored in a single place for easy maintenance.)

Doing something like this is what I'm about to do but I'd rather avoid both the overhead of the runtime check and writing any code that must examine the current database flavor to run properly...

if (nhSession.GetSessionImplementation().Factory.Dialect == NHibernate.Dialect.MySQL5Dialect) {
  // grab the MySQL named query here                
} else {
  // grab the SQL Server named query here
}

Is there a way to do something like this instead? (the below is wishful pseudo-coding...)

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<dialect-filter dialect="mysql">
  <sql-query name="spForMySQL" callable="true">
    <query-param name="mySqlP1" type="int" />
    <return alias="OutType" class="Domain.ResultType, Domain">
      <return class="ResultType">
        <return-property column="col1" name="Id" />
        <return-property column="col2" name="Name" />
      </return>
    </return>
    call spName(:mySqlP1)
  </sql-query>
</dialect-filter>
<dialect-filter dialect="SQLServer">
  <sql-query name="spForSQLServer" callable="true">
    <query-param name="sqlServerP1" type="int" />
    <return alias="OutType" class="Domain.ResultType, Domain">
      <return class="ResultType">
        <return-property column="col1" name="Id" />
        <return-property column="col2" name="Name" />
      </return>
    </return>
    exec spForSQLServer @sqlServerP1= :sqlServerP1
  </sql-query>
</dialect-filter>
</hibernate-mapping>