【问题标题】:NHibernate - "In" query with composite idNHibernate - 具有复合 ID 的“In”查询
【发布时间】:2010-07-15 11:41:28
【问题描述】:

我正在尝试对映射为复合键的 id 对象集合(实现为具有两个整数 id 成员的简单类)执行“in”查询,当我查询时看到一些奇怪的结果使用条件 api 使用 Restrictions.In 并使用 NHibernate.Linq 使用 idList.Contains

这是一个示例用法:

    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

这是我的密钥的映射:

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

这是生成的结果 SQL:

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 */)

对我来说,这个逻辑似乎有缺陷,它对每个复合键 ID 执行单独的“In”查询;这不会返回错误的结果吗?

作为参考,我在我的键类上正确实现了 .Equals 和 .GetHashCode,所以我确定这不是问题。

【问题讨论】:

    标签: nhibernate linq-to-nhibernate


    【解决方案1】:

    是的,它会返回错误的结果,定义传递的复合 ID 值的任何对都可以评估为真,因此当您请求例如 [ [1,1], [2,2], [3,3] ] 此查询还将获取 [ [1,2]、[1,3]、[2,1] [2,3]、[3,1]、[3,2] 等]..

    我现在能想到的唯一解决方案是分离对...例如

    (this_.QualificationAreaId = 1 AND this_.QualificationLevelId = 1) 或

    (this_.QualificationAreaId = 2 AND this_.QualificationLevelId = 2) 或

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

    等等……

    【讨论】:

    • 感谢您的确认;我想我可以走分离路线,但这有点痛苦 - 感谢您的意见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多