10
votes

Nibernate Comment puis-je interroger contre une propriété IList?

J'essaie d'interroger une propriété IList sur l'une de mes classes de domaine utilisant NHibernate. Voici un exemple simple à démontrer: xxx pré>

mappé comme ceci: p> xxx pré>

p>

et je suis capable de enregistrer et récupérer juste bien. Maintenant, pour interroger les instances de ma classe de domaine où la propriété Tags contient une valeur spécifiée: P>

var demos = this.session.CreateQuery("from Demo d where :t in elements(d.Tags)")
            .SetParameter("t", "a")
            .List<Demo>();


0 commentaires

6 Réponses :


3
votes

Vous devez utiliser des souscritées non pas des alias. Cela devrait fonctionner:

var demos = this.session.CreateCriteria<Demo>()
            .CreateCriteria("Tags")
            .Add(Restrictions.Eq("Tag", "a"))
            .List<Demo>();


5 commentaires

Cela entraîne également le message d'erreur: la collection n'était pas une association: Demo.Tags


Vous n'avez pas spécifié de table pour votre sac . Je ne connais pas ce genre de cartographie. Est-ce destiné?


Ne fait aucune différence si je spécifie le nom de la table ou permettez-le d'utiliser la valeur par défaut (identique au nom de la propriété dans ce cas).


D'accord, j'ai finalement vu quel est votre problème. Tags est une liste , pas une liste . Vous ne pouvez pas faire cela en utilisant des critèresAPI. Voir ce fil: Mail-Archive.com/nibernate-développement@ googlegroups.com/...


Cela devrait être marqué comme réponse, c'est le premier que je suis venu à cela vraiment l'astuce!



3
votes

HQL:

from Demo d where :val in elements(d.Tags)


1 commentaires

Je sais que ça marche. Ci-dessus je reconnais que ça fait. Mais je me frappe et crie de devoir écrire une énorme requête dynamique en fonction de l'entrée de mon utilisateur. Merci d'avoir regardé cela. J'apprécie cela.



4
votes

Ainsi, à cause des limitations de l'API de critères, j'ai décidé de plier mes classes de domaine à l'aptitude.

J'ai créé une classe d'entité pour la balise. Je ne pouvais même pas la créer comme objet de valeur. Il devait avoir sa propre pièce d'identité.

Je me sens sale maintenant. Mais être capable de construire une requête dynamique sans recourir à la manipulation de chaîne était plus importante pour moi que de rester fidèle au domaine.


1 commentaires

Il y a un moyen de faire cela par des critères API. Je l'ai emballé dans une réponse séparée.



2
votes

La commutation d'une classe sur une chaîne est un compromis. L'utilisation de HQL au lieu de l'ICRITRIERIE est une autre. Il y a un troisième compromis cependant ... Utilisez personnalisé SQL. Essayez ceci. XXX PRE>

Il en résulte que le SQL Follwing est généré par NHibernate 2.1.2.4000 ... P>

exec sp_executesql N'SELECT this_.Id as Id2_0_, this_.Version as Version2_0_, this_.Name as Name2_0_ FROM Demo this_ WHERE EXISTS (SELECT 1 FROM [Tags] custom_sql_t WHERE custom_sql_t.[DemoId] = this_.[Id] AND custom_sql_t.[Tag] = @p0)',N'@p0 nvarchar(1)',@p0=N'a'


0 commentaires

4
votes

Comme documenté ici:

17.1.4.1. Alias ​​et références de propriétés h3>

Nous pouvons utiliser: P>

var demos = this.session.CreateCriteria<Demo>()
        .CreateAlias("Tags", "t")

        // instead of this
        // .Add(Restrictions.Eq("t", "a"))

        // we can use the .elements keyword
        .Add(Restrictions.Eq("t.elements", "a"))

        .List<Demo>();


0 commentaires

0
votes

Ceci est possible en créant un critère distinct: xxx


0 commentaires