2010-04-09 5 views
1

Comment utiliser une procédure stockée de NHibernate tout en conservant la solution database-agnostic et la base de code propre des instructions switch avec un cas pour chaque Dialect?Mappage de requêtes nommé NHibernate conditionnel par Dialect

Je m'attends à créer une requête nommée par implémentation de base de données contenant le contenu de l'implémentation sql spécifique à la base de données de la procédure. Mon dilemme est de savoir comment appeler de façon conditionnelle la bonne requête nommée. Plus précisément, nous testons les deux dialectes MySQL et MS SQL Server 2008 pour le moment.

Est-ce que quelqu'un sait comment créer une carte de requête nommée conditionnelle par dialecte? (Cela permettrait de stocker les différentes implémentations de procédures stockées en un seul endroit pour une maintenance aisée.)

Faire quelque chose comme ceci est ce que je vais faire, mais je préfère éviter les frais généraux de la vérification de l'exécution. et tout code écrit qui doit examiner la saveur de la base de données actuelle de fonctionner correctement ...

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

est-il un moyen de faire quelque chose comme ça à la place? (Ci-dessous est le pseudo-codage ... wishful)

<?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> 

Répondre

1

La meilleure façon d'accomplir quelque chose comme ça serait de mettre vos cartes dans différents ensembles et des cartes de charge en fonction de la base de données que vous opérez contre.

En utilisant FluentNHibernate il ressemblerait à ceci:

bool isSql = true; 

var factory = Fluently.Configure() 
... 
.Mappings(x => isSql ? x.HbmMappingFromAssemblyOf<SqlServerMaps>() : x.HbmMappingFromAssemblyOf<MySqlMaps>())