2009-08-06 7 views
2

Compte tenu de cette cartographie héritage:entités Filtrage par sous-type avec NHibernate.Linq

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <class name="User" table="[User]" abstract="true"> 
     <joined-subclass name="SubUser1" table="SubUser1"> 
      <key column="UserId" /> 
      ... 
     </joined-subclass> 
     <joined-subclass name="SubUser2" table="SubUser2"> 
      <key column="UserId" /> 
      ... 
     </joined-subclass> 
     <joined-subclass name="SubUser3" table="SubUser3"> 
      <key column="UserId" /> 
      ... 
     </joined-subclass> 
    </class> 
</hibernate-mapping> 

Comment faire une requête pour toutes les instances de SubUser2 et SubUser3? Je réalise que je peux le faire:

session.Linq<User>().OfType<SubUser2>() 

mais cela ne me permet que de filtrer par un seul type. J'ai essayé ceci:

session.Linq<User>().Where(user => user is SubUser2) 

mais qui a abouti à cette erreur:

could not resolve property: of: User 

Toutes les idées sur la façon d'exprimer une requête sur plusieurs sous-types?

+0

J'ai le même problème. Savez-vous comment le faire dans les critères? Quand c'est possible dans les critères, il doit être possible de faire fonctionner l'opérateur "is". – Paco

Répondre

1

Pour autant que je peux dire, ce n'est pas possible. Peut-être que ce sera dans le futur. Je sais qu'ils acceptent les patches :-)

J'ai seulement environ 500 enregistrements et 4 types, et j'interroge habituellement sur 2 ou 3 types en même temps. Pour l'instant, j'applique le filtre sur chaque type dans la base de données, puis concatène les ensembles de résultats et effectue l'ordonnancement et la pagination en mémoire.

Ce n'est pas la solution la plus efficace, mais fonctionne très bien. J'ai choisi de ne pas ajouter de colonne discriminante superflue à la table Utilisateur uniquement pour activer cette requête.

0

Qu'en est-il quelque chose comme ceci:

// Get them in 2 queries 
var sub2 = session.Linq<SubUser2>().Select(x => x).ToList(); 
var sub3 = session.Linq<SubUser3>().Select(x => x).ToList(); 

// Join together in memory 
var sub2And3 = sub2.OfType<User>().Union(sub3.OfType<User>()); 
+1

Malheureusement, cela ne me permet pas d'exprimer des requêtes sur la base de données. J'appliquerais le filtrage, la commande et la pagination en mémoire. –

+0

Peut-être alors vous pourriez appliquer Union sur la base de données (mais pas sûr si elle est supportée). –

+0

Je l'ai essayé quand j'ai lu votre réponse, Union n'est pas supporté. –