2010-07-15 6 views
0

J'essaie d'effectuer une requête "in" sur une collection d'objets ID (implémentée en tant que classe simple avec deux membres d'entiers) qui sont mappés en tant que clés composées et je « m à voir des résultats étranges quand je requête en utilisant l'api de critères à l'aide Restrictions.In et à l'aide NHibernate.Linq à l'aide idList.ContainsNHibernate - requête "In" avec l'ID composite

Voici un exemple d'utilisation:

Public Function GetByMultipleIds(ByVal ids As ICollection(Of QualificationKey)) As IList(Of Qualification) Implements IQualificationRepository.GetByMultipleIds 
     Dim query = Session.CreateCriteria(Of Qualification)() 
     query.Add(Restrictions.In("Id", ids.ToArray())) 
     Return query.List(Of Qualification)() 
    End Function 

Voici le mappage pour ma clé :

<composite-id name="Id" class="QualificationKey"> 
     <key-property name="QualificationAreaId" column="QualificationAreaId"/> 
     <key-property name="QualificationLevelId" column="QualificationLevelId"/> 
    </composite-id> 

Voici le SQL résultant qui est généré:

SELECT this_.QualificationAreaId                 as Qualific1_6_2_, 
     this_.QualificationLevelId                 as Qualific2_6_2_, 
     this_.Version                    as Version6_2_, 
     this_.Rank                     as Rank6_2_, 
     (SELECT QualificationArea.QualificationAreaTypeId 
     FROM QualificationArea 
     WHERE QualificationArea.QualificationAreaId = this_.QualificationAreaId) as clazz_2_, 
     qualificat2_.QualificationAreaId               as Qualific1_7_0_, 
     qualificat2_.Name                   as Name7_0_, 
     qualificat2_.QualificationAreaTypeId              as Qualific2_7_0_, 
     qualificat2_.QualificationAreaPermissionId             as Qualific4_7_0_, 
     qualificat2_.Description                 as Descript5_7_0_, 
     qualificat2_.QualificationAreaExpirySettingId            as Qualific6_7_0_, 
     qualificat2_.DisplayOrder                 as DisplayO7_7_0_, 
     qualificat2_.DateCreated                 as DateCrea8_7_0_, 
     qualificat2_.DateUpdated                 as DateUpda9_7_0_, 
     qualificat2_.ShowOnSignupForm1                as ShowOnS10_7_0_, 
     qualificat2_.ShowOnSignupForm2                as ShowOnS11_7_0_, 
     qualificat2_.ShowOnSignupForm3                as ShowOnS12_7_0_, 
     qualificat2_.AgencyId                  as AgencyId7_0_, 
     qualificat3_.QualificationLevelId               as Qualific1_47_1_, 
     qualificat3_.Name                   as Name47_1_, 
     qualificat3_.Description                 as Descript3_47_1_, 
     qualificat3_.DateCreated                 as DateCrea4_47_1_, 
     qualificat3_.DateUpdated                 as DateUpda5_47_1_, 
     qualificat3_.AgencyId                  as AgencyId47_1_, 
     dbo.IsQualificationLevelAssociatedWithAnyQualifications(qualificat3_.QualificationLevelId) as formula21_1_ 
FROM Qualification this_ 
     inner join QualificationArea qualificat2_ 
     on this_.QualificationAreaId = qualificat2_.QualificationAreaId 
     inner join QualificationLevel qualificat3_ 
     on this_.QualificationLevelId = qualificat3_.QualificationLevelId 
WHERE this_.QualificationAreaId in (1 /* @p0 */,2 /* @p1 */,3 /* @p2 */) 
     and this_.QualificationLevelId in (1 /* @p3 */,2 /* @p4 */,3 /* @p5 */) 

Pour moi, cette logique semble défectueux, il est séparé l'exécution « Dans » requêtes pour chacun des composites ids clés; cela ne retournerait-il pas des résultats incorrects?

Pour référence, j'ai .Equals et .GetHashCode correctement mis en œuvre sur ma classe de clé, donc je suis sûr que ce n'est pas le problème.

Répondre

1

oui il va retourner des résultats erronés, l'une des paires définies les valeurs d'id-composite passées peut évaluer à vrai, alors que vous demandez par exemple [[1,1], [2,2], [3,3 ]] cette requête ira également chercher [[1,2], [1,3], [2,1] [2,3], [3,1], [3,2] etc.]

la seule solution que je peux penser est maintenant une disjonction des paires ... par exemple

(this_.QualificationAreaId = 1 ET this_.QualificationLevelId = 1) ou

(this_.QualificationAreaId = 2 et this_.QualificationLevelId = 2) OU

(this_.QualificationAreaId = 3 et this_.QualificationLevelId = 3)

etc ....

+0

merci pour confirmer ceci; Je suppose que je peux aller sur la voie de la disjonction, mais c'est un peu pénible - merci pour la contribution. – DanP