2010-08-04 3 views
1

Je dois ajouter dynamiquement des requêtes nommées à l'objet de configuration NHibernate. Les moteurs de recherche renvoient quelques occurrences référençant NamedSQLQueryDefinition ou NamedQueryDefinition. Voici ce que je tente de faire. Je ne sais pas quoi fournir au constructeur NamedSQLQueryDefinition pour créer une requête avec succès. Quelqu'un peut-il fournir un exemple de comment créer une nouvelle NamedSQLQueryDefinition dans le bon sens? Merci!!Comment la classe NamedSQLQueryDefinition peut-elle être utilisée dynamiquement en tant qu'équivalent de requête sql?

Session initialiseur:

private static ISessionFactory CreateSessionFactory() 
    { 
     var configuration = new Configuration(); 

     return Fluently.Configure(configuration.Configure()) 
      .ExposeConfiguration(AddQueries) 
      .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>()) 
      .Mappings(m => m.HbmMappings.AddFromAssemblyOf<Program>()) 
      .BuildConfiguration() 
      .BuildSessionFactory(); 
    } 

Les AddQueries ressemblerait à quelque chose comme ceci:

private static void AddQueries(Configuration cfg) 
    { 
     var nameQuery = new NamedSQLQueryDefinition("exec pr_GETCustomer ?", ...) 

     cfg.NamedSQLQueries.Add("pr_GETCustomer", nameQuery); 
     var cust = cfg.GetClassMapping(typeof (Customer)); 

     cust.LoaderName = "pr_GETCustomer"; 
    } 

PS: Je suis en train cette route parce que Fluent NHibernate ne met pas en œuvre un moyen de configurer le chargeur & sql-query éléments du fichier hbm.

Répondre

1

La méthode AddQueries serait implémentée comme suit pour «corriger» l'absence de support NHibernate de Loader. L'astuce consiste à configurer correctement la valeur INativeSQLQueryReturn [] pour contenir le mappage des colonnes de la table vers les propriétés de l'entité. Il doit imiter le contenu de l'élément return de sql-query dans le fichier HBM où la classe (avec l'espace de noms) et les mappages de propriétés sont définis (voir XML ci-dessous). Merci à @jimbobmcgee pour m'avoir initié dans cette direction!

private static void AddQueries(Configuration cfg) 
{ 
    var namedQuery = new NamedSQLQueryDefinition(
     "exec dbo.pr_GETCustomers @CustomerID=?", 
     new INativeSQLQueryReturn[] 
      { 
       new NativeSQLQueryRootReturn(
        "Customers", 
        "VehicleInfo.Entities.Customers", 
        new Dictionary<string, string[]> 
         { 
            {"CustomerID", new[] {"CustomerID"}}, 
            {"CompanyName", new[] {"CompanyName"}} 
        }, 
        LockMode.Read) 
      }, 
     new List<string> { "dbo.Customers" }, 
     true, 
     null, 
     15, 
     1000, 
     FlushMode.Auto, 
     CacheMode.Normal, 
     false, 
     "", 
     null, 
     true); 

    cfg.NamedSQLQueries.Add("pr_GETCustomers", namedQuery); 
    var cust = cfg.GetClassMapping(typeof(Customers)); 

    cust.LoaderName = "pr_GETCustomers"; 
} 

Exemple de fichier HBM qui fait la même chose:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
    default-access="property" auto-import="true" 
    default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" 
     mutable="true" name="VehicleInfo.Entities.Customers, VehicleInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Customers"> 
     <id name="CustomerID" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
      <column name="CustomerID" /> 
      <generator class="assigned" /> 
     </id> 

     <property name="CompanyName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
      <column name="CompanyName" /> 
     </property> 

     <loader query-ref="pr_GETCustomers"/> 

     <sql-insert callable="true" check="none">exec dbo.pr_INSERTCustomers @CompanyName=?, @CustomerID=?</sql-insert> 
     <sql-update callable="true" check="none">exec dbo.pr_UPDATECustomers @CompanyName=?, @CustomerID=?</sql-update> 
     <sql-delete callable="true" check="none">exec dbo.pr_DELETECustomers @CustomerID=?</sql-delete> 
    </class> 
    <sql-query name="pr_GETCustomers"> 
     <return alias="cust" class="VehicleInfo.Entities.Customers, VehicleInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> 
      <return-property name="CustomerID" column="CustomerID"></return-property> 
      <return-property name="CompanyName" column="CompanyName"></return-property> 
     </return> 
     exec dbo.pr_GETCustomers @CustomerID=? 
    </sql-query> 
</hibernate-mapping> 
0

Je suis assez nouveau à ce sujet, mais la plupart des paramètres semblent être déterminables à partir des attributs que vous pouvez fournir dans le fichier HBM. Cela dit, je ne suis pas sûr de ce que sont les QuerySpaces. Le plus proche que je dois ce que je pense que vous essayez d'atteindre est d'utiliser les éléments suivants (non testé):

ISQLQuery q = session.CreateSQLQuery("exec pr_GETCustomer :p1"); 

if (q is SqlQueryImpl) 
{ 
    IDictionary<string, TypedValue> namedParams = new Dictionary<string, TypedValue>(); 
    namedParams.Add("p1", new TypedValue(NHibernateUtil.Int32, 12345); 

    IDictionary<string, string> paramTypes = new Dictionary<string, string>(); 

    NativeSQLQuerySpecification spec = 
     (q as SqlQueryImpl).GenerateQuerySpecification(namedParams); 

    NativeSQLQueryDefiniton def = new NativeSQLQueryDefiniton(
     spec.QueryString, 
     spec.SqlQueryReturns, 
     spec.QuerySpaces, 
     false, 
     null, 
     -1, 
     -1, 
     FlushMode.Never, 
     CacheMode.Normal, 
     true, 
     "blah", 
     paramTypes, 
     false 
    ); 
} 

De toute évidence, je n'aime pas le casting de SqlQueryImpl. J'espère que, une fois que l'un d'entre nous l'aura fait une fois, des propriétés obscures comme querySpaces pourront être comprises, donc vous n'aurez pas à le faire.

Ce n'est pas que je m'attends à 100% de travail, mais il peut être plus réalisable à partir d'ici.

+0

Merci, je vais essayer cette approche. J'essayais aussi de comprendre ce que QuerySpaces était et je n'avais pas envie de creuser dans la source de NHibernate. –

Questions connexes