2010-11-16 3 views
0

J'utilise NHibernate depuis un certain temps maintenant, mais la plupart du temps avec la génération de modèles de persistance automatique basée sur les conventions, puis en effectuant des opérations CRUD de base sur les objets.Implémentation d'une requête complexe dans NHibernate?

J'ai maintenant besoin d'exécuter une requête plutôt désagréable contre un système hérité avec une main pleine de paramètres (la plus grande partie de la clause where doit être paramétrée). Je ne sais pas si je devrais définir les objets individuels, puis essayer d'implémenter la requête complexe OU simplement utiliser le SQL natif pour définir la requête. Je ne suis pas clair sur la syntaxe correcte pour définir la requête dans un fichier hbm.xml. La requête SQL native suit. Merci à tous ceux qui peuvent m'aider à régler ce problème.

WITH CTE AS (SELECT 
    substr(KEY1||KEY2||KEY3||'-'||digits(KEY4)||'-'||digits(KEY5),1,17) KEY_ID, 
    SUM(CASE WHEN BATCH between 200801001 and 200812999 THEN TRANSACTION_AMOUNT ELSE 0 END) AS _2008AMOUNT, 
    SUM(CASE WHEN BATCH between 200901001 and 200912999 THEN TRANSACTION_AMOUNT ELSE 0 END) AS _2009AMOUNT, 
    SUM(CASE WHEN BATCH between 201001001 and 201012999 THEN TRANSACTION_AMOUNT ELSE 0 END) AS _2010AMOUNT 

    FROM _SCHEMA.TRANSACTIONS 

    WHERE OWNER='02' 
    AND TRANSACTION_TYPE in ('A','B') 
    AND BATCH between 200801000 AND 201012999 

    GROUP BY KEY1, KEY2, KEY3, KEY4, KEY5 

    HAVING SUM(CASE WHEN BATCH between 200801001 and 200812999 THEN TRANSACTION_AMOUNT ELSE 0 END) 0 
    OR SUM(CASE WHEN BATCH between 200901001 and 200912999 THEN TRANSACTION_AMOUNT ELSE 0 END) 0 
    OR SUM(CASE WHEN BATCH between 201001001 and 201012999 THEN TRANSACTION_AMOUNT ELSE 0 END) 0 
    ) 


    SELECT 
    B.OWNER 
    ,CTE1.MAX_ITEM_AMOUNT 
    ,CTE1.SUM_ITEM_AMOUNT 
    ,B.PRIMARY_SECONDARY_IDENTITY 
    ,B.PRIMARY_ID 
    ,B.PRIMARY_NAME 
    ,B.KEY_ID 
    ,B.KEY_AMOUNT 
    ,CASE(B.KEYCLASS) WHEN 'C' THEN 'CLASS1' WHEN 'S' THEN 'CLASS2' WHEN 'M' THEN 'CLASS3' WHEN 'F' THEN 'CLASS4' END AS KEYCLASS 
    ,NA.PRIMARY_CT AS PRIMARY_CITY 
    ,NA.PRIMARY_ST AS PRIMARY_STATE 
    ,B.KEY_EFFECTIVE_DATE 
    ,B.KEY_ENTRY_DATE 
    ,CTE._2008AMOUNT 
    ,CTE._2009AMOUNT 
    ,CTE._2010AMOUNT 
    ,B.EMPLOYEE_NAME 

    FROM CTE 

    JOIN _SCHEMA.TABLE2 B ON CTE.KEY_ID = B.KEY_ID 

    JOIN (
    SELECT 
    PRIMARY_SECONDARY_IDENTITY 
    , MAX(ITEM_AMOUNT) AS MAX_ITEM_AMOUNT 
    , SUM(ITEM_AMOUNT) AS SUM_TTEM_AMOUNT 
    FROM CTE 
    JOIN _SCHEMA.TABLE2 B ON CTE.KEY_ID = B.KEY_ID 
    GROUP BY PRIMARY_SECONDARY_IDENTITY 
    ) CTE1 ON CTE1.PRIMARY_SECONDARY_IDENTITY = B.PRIMARY_SECONDARY_IDENTITY 

    JOIN _SCHEMA.TABLE3 NA ON B.PRIMARY_ID = NA.KEY1 || DIGITS(NA.KEY2) 

    ORDER BY MAX_ITEM_AMOUNT DESC, PRIMARY_SECONDARY_IDENTITY 
+0

Avez-vous répondu à la question? Si oui, veuillez l'accepter pour fournir une bonne solution aux collègues de notre SO à la recherche d'une telle solution. –

Répondre

5

Ce type de transaction doit être traité par le biais de requêtes nommées. NHibernate permet certaines requêtes nommées pré-configurées qu'une simple opération CRUD ne peut pas faire. Je vous suggère de jeter un œil sur l'utilisation de ceux-ci dans la documentation de NHibernate.

15.2. Named SQL queries

D'autre part, vous pouvez être intéressé par des requêtes SQL natives.

9.3.5. Queries in native SQL

+0

D'accord. Voici un exemple: http://ayende.com/Blog/archive/2009/04/17/nhibernate-mapping-ndash-named-queries-ltquerygt-and-ltsql-querygt.aspx –

+0

Merci, mon problème avec la documentation et la plupart des exemples sont assez anémiques. Il est difficile de voir l'impact des expressions de table communes, Group By, et des sous-requêtes. La documentation semble impliquer qu'il y a des manières spécifiques qu'une jointure doit être exprimée, même en SQL natif, mais rien ne se rapproche de traiter les détails impliqués dans la requête ci-dessus. – tlum

+0

Peut-être devriez-vous envisager d'écrire une procédure stockée avec ce code, et faire de cette procédure stockée une requête nommée. –