需要帮助才能正确删除NHibernate中的重复项

时间:2010-06-11 20:49:50

标签: nhibernate

这是我遇到的问题。 我有一个包含100多条记录的数据库。 我正在翻阅数据,一次获得9个结果。 当我添加一个检查以查看项目是否处于活动状态时,它会导致结果开始加倍。

一点背景: “产品”是实际的产品系列 “ProductSkus”是产品系列中存在的实际产品 当Product中有超过1个ProductSku时,它会导致返回重复的条目。

请参阅下面的NHibernate查询:

result = this.Session.CreateCriteria<Model.Product>()                 
                .Add(Expression.Eq("IsActive", true))
                .AddOrder(new Order("Name", true))
                .SetFirstResult(indexNumber).SetMaxResults(maxNumber)

                // This part of the query duplicates the products
                .CreateAlias("ProductSkus", "ProdSkus", JoinType.InnerJoin)
                .Add(Expression.Eq("ProdSkus.IsActive", true))

                .CreateAlias("ProductToSubcategory", "ProdToSubcat")
                .CreateAlias("ProdToSubcat.ProductSubcategory", "ProdSubcat")
                .Add(Expression.Eq("ProdSubcat.ID", subCatId))

                // This part takes out the duplicate products - Removes too many items...
                // Turns out that with .SetFirstResult(indexNumber).SetMaxResults(maxNumber)
                // it gets 9 records back then the duplicates are removed.  
                // Example: 
                //      Total Records over 100
                //      Max = 9
                //      4 Duplicates removed
                //      Yields 5 records when there should be 9
                // Why???  This line is ran in NHibernate on the data after it has been extracted from the SQL server.
                .SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer())

                .List<Model.Product>();

我添加了DistinctRootEntityResultTransformer来清理重复项。问题在于它将包含重复的9条记录拉回来。然后DistinctRootEntityResultTransformer清除9条记录中的重复项。我基本上需要在SQL服务器上运行一个独特的语句来开始。

然而,由于NHibernate默认希望在语句的select部分中的每个表中添加每个字段,因此SQL上的不同之处不起作用。我只使用属于根表的字段开始(Model.Product)。如果我可以告诉NHibernate不要将连接表中的字段添加到语句的选择部分并添加Distinct,那么它将起作用。

我使用NHibernare Profiler查看实际查询:

SELECT   top 9 this_.ID                          as ID351_3_,
           this_.Name                        as Name351_3_,
           this_.Description                 as Descript3_351_3_,
           this_.IsActive                    as IsActive351_3_,
           this_.ManufacturerID              as Manufact5_351_3_,
           prodskus1_.ID                     as ID373_0_,
           prodskus1_.Description            as Descript2_373_0_,
           prodskus1_.PartNumber             as PartNumber373_0_,
           prodskus1_.Price                  as Price373_0_,
           prodskus1_.IsKit                  as IsKit373_0_,
           prodskus1_.IsActive               as IsActive373_0_,
           prodskus1_.IsFeaturedProduct      as IsFeatur7_373_0_,
           prodskus1_.DateAdded              as DateAdded373_0_,
           prodskus1_.Weight                 as Weight373_0_,
           prodskus1_.TimesViewed            as TimesVi10_373_0_,
           prodskus1_.TimesOrdered           as TimesOr11_373_0_,
           prodskus1_.ProductID              as ProductID373_0_,
           prodskus1_.OverSizedBoxID         as OverSiz13_373_0_,
           prodtosubc2_.ID                   as ID362_1_,
           prodtosubc2_.MasterSubcategory    as MasterSu2_362_1_,
           prodtosubc2_.ProductID            as ProductID362_1_,
           prodtosubc2_.ProductSubcategoryID as ProductS4_362_1_,
           prodsubcat3_.ID                   as ID352_2_,
           prodsubcat3_.Name                 as Name352_2_,
           prodsubcat3_.ProductCategoryID    as ProductC3_352_2_,
           prodsubcat3_.ImageID              as ImageID352_2_,
           prodsubcat3_.TriggerShow          as TriggerS5_352_2_
 FROM     Product this_
     inner join ProductSku prodskus1_
       on this_.ID = prodskus1_.ProductID
          and (prodskus1_.IsActive = 1)
     inner join ProductToSubcategory prodtosubc2_
       on this_.ID = prodtosubc2_.ProductID
     inner join ProductSubcategory prodsubcat3_
       on prodtosubc2_.ProductSubcategoryID = prodsubcat3_.ID
 WHERE    this_.IsActive = 1 /* @p0 */
     and prodskus1_.IsActive = 1 /* @p1 */
     and prodsubcat3_.ID = 3 /* @p2 */
 ORDER BY this_.Name asc

如果我手动修改查询并直接在SQL服务器上运行,我会得到我想要的结果集(我删除了select部分中的所有额外字段并添加了DISTINCT):

SELECT DISTINCT  top 9 this_.ID              as ID351_3_,
           this_.Name                        as Name351_3_,
           this_.Description                 as Descript3_351_3_,
           this_.IsActive                    as IsActive351_3_,
           this_.ManufacturerID              as Manufact5_351_3_,
 FROM     Product this_
     inner join ProductSku prodskus1_
       on this_.ID = prodskus1_.ProductID
          and (prodskus1_.IsActive = 1)
     inner join ProductToSubcategory prodtosubc2_
       on this_.ID = prodtosubc2_.ProductID
     inner join ProductSubcategory prodsubcat3_
       on prodtosubc2_.ProductSubcategoryID = prodsubcat3_.ID
 WHERE    this_.IsActive = 1 /* @p0 */
     and prodskus1_.IsActive = 1 /* @p1 */
     and prodsubcat3_.ID = 3 /* @p2 */
 ORDER BY this_.Name asc

我现在必须要问的一个重要问题是......

我必须在NHibernate Query中更改哪些内容才能获得完全相同的结果?

提前致谢。

1 个答案:

答案 0 :(得分:1)

以下是其他地方发布的答案:Get Distinct result set from NHibernate using Criteria API?