Нужна помощь, чтобы правильно удалить дубликаты в NHibernate - PullRequest
0 голосов
/ 12 июня 2010

Вот проблема, с которой я столкнулся.У меня есть база данных с более чем 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-сервере запускался отдельный оператор.

Однако отдельный SQL не сработает, так как NHibernate по умолчанию хочет добавить каждое поле из каждой таблицы в выделенной части.из заявления.Для начала я использую только те поля, которые принадлежат корневой таблице (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, я получаю нужный набор результатов (я удалил все дополнительные поля в разделе выбора и добавил 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, чтобы в конечном итоге получить точно такой же результат?

Заранее спасибо.

1 Ответ

1 голос
/ 01 апреля 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...