0

Привета У меня есть это SQL и должен перевести в NHibernate QueryOverпродукта с последними 4 поставщиков на дате сделки

SELECT S.Number, S.Description, S.BrandDescription, subquery.vendornumber, subquery.vendorname 
FROM Stocks.Stock S left join 
        (select vendorNumber, VendorName, POLID, LastTransactionDate from 
         (
         SELECT top 4 v.Number vendorNumber, v.Name VendorName, PLL.Id POLID, max(por.TransactionDate) as LastTransactionDate, 
         ROW_NUMBER() OVER(PARTITION BY v.Number ORDER BY max(por.TransactionDate) DESC) AS rk 
         FROM Purchasing.PurchaseOrderLineItem PLL 
         inner join Purchasing.PurchaseOrder po on PLL.PurchaseOrderId = po.Id 
         inner join Purchasing.PurchaseOrderVendor POV on po.Id = POV.PurchaseOrderId 
         inner join Purchasing.Vendor V on pov.VendorId = v.Id 
         left outer join Purchasing.PurchaseOrderReceipt POR on PLL.Id = por.PurchaseOrderLineItemId 
         group by v.Number, v.Name,PLL.Id 
         order by LastTransactionDate desc 
         ) subquery 
         where subquery.rk = 1) B on PL.Id = b.POLID 

Или просто объяснить это просто увидеть его упрощенной версию

Select * from master m 
outer apply (select top 4 * From Details d where m.Id = d.Id order by someColumns desc)o 

Я думаю, что мы не может использовать подзапрос в качестве производной таблицы в nhibernate. Если у вас есть предложения, пожалуйста, поделитесь.

Благодаря

+0

В гайковерте NHibernate FROM определяется отображением класса/сущности, JOIN определяется путем сопоставления ссылок. Таким образом, указанный выше SQL-запрос не будет работать. Решением здесь является: 1) Create View - и инкапсулировать всю сложность - нанести на карту его как Entity 2), используя исходный SQL-запрос для получения этих данных. Любое другое решение не подходит для ORM в общем –

+0

Спасибо @ RadimKöhler за ответ. Я выполнил хранимую процедуру, которая работает нормально, но мой босс ничего не говорит о каких-либо вещах вне объектов отображения NHibernate из-за ограничения безопасности. Я также пытался создать два отдельных результата запроса и объединить или присоединиться к этому требованию. Любая идея или предложение? – Ammad

+0

Я бы попытался использовать либо представление, которое затем можно было бы отобразить как сущность, либо комбинацию «C#» - точно так же, как вы сказали. Но дело в том, что такой сложный запрос, который вам нужно создать, просто за пределами возможностей ORM-мира ... извините, чтобы не было лучшего ответа. –

ответ

0

Я был продолжать работать над этим и нашел, что это может быть очень трудно, если хотите сделать полностью с QueryOver. Я хочу показать, как я это сделал.

Сначала я взял всех продавцов с StockID, чтобы позже присоединиться к StockQuery. .

  var stockVendors = 
      Session.QueryOver<Vendor>(() => V) 
       .Left.JoinQueryOver(p => V.Stock,() => sstk) 
       .Where(sstk.Number !=null) 
       .OrderBy(Projections.Max(() => V.TransactionDate)).Desc() 
       .ThenBy(() => sstk.Number).Asc() 
       .ThenBy(() => sv.Number).Asc() 
       .SelectList(
        lst => 
        lst.SelectGroup(() => V.Name).WithAlias(() => svhModal.VendorName) 
         .SelectGroup(() => V.Number).WithAlias(() => svhModal.VendorNumber) 
         .SelectGroup(() => sstk.Number).WithAlias(() => svhModal.StockNumber) 
         .Select(Projections.Max(() => V.TransactionDate)).WithAlias(() => svhModal.LastTransactionDate) 

) .TransformUsing (Transformers.AliasToBean()) List();

Затем выберите Шток только

var stockDetail = Session.QueryOver<Stock>(() => stk) 
      .Where(soneCriteria) 
      .SelectList(list => list 
       .Select(() => stk.Id).WithAlias(() => sdrModal.Id) 
       .Select(() => stk.Number).WithAlias(() => sdrModal.Number) 
.TransformUsing(Transformers.AliasToBean<StockDetailReportModal>()) 
        .List<StockDetailReportModal>(); 

IList<StockVendor> vlst2 = null; 
      IList<StockDetail> newStock = new List<StockDetail>(); 

Здесь начинается две петли, чтобы заполнить объект List с каждой акции и ее 5 лучших поставщиков из списка поставщиков. Loop from Stockdetail получается из запроса и внутри цикла из результата поставщика, отфильтрованного по внешнему контуровному штоку, получить первые 5 поставщиков только в цикле, когда они просто вернут результат для отчета. Его работа прекрасна.

foreach (StockDetail ostk in stockDetail) 
     { 
      stkid = ostk.Number; 
      vlst2 = (from v in stockVendors where v.StockNumber == stkid orderby v.LastTransactionDate descending select v).ToList<StockVendor>(); 

      vndrcnt = 0; 
      stok = new StockDetail 
      { 
       Id = ostk.Id, 
       Number = ostk.Number, 
//// other fields too here 
      }; 

      if (vlst2.Count() == 0) 
      { 
       newStock.Add(stok); 
      } 

      foreach (StockVendor vn in vlst2) 
      { 
       if (vndrcnt == 0) 
       { 
        stok.VendorName = vn.VendorName; 
        stok.VendorNumber = vn.VendorNumber; 
      // other fields here... 
        newStock.Add(stok); 
       } 
       else 
       { 
        newStock.Add(new StockDetail 
        { 
         Id = ostk.Id, 
         Number = ostk.Number, 
         VendorName = vn.VendorName, 
         VendorNumber = vn.VendorNumber, 
// adding vendor information in stock record. 
         }); 
        } 
        vndrcnt++; 
        if (vndrcnt >= 4) 
         break; 
       } 

Это решило мою проблему и добились этого после изучения многих дней. Вы можете найти лучший подход, поэтому, пожалуйста, поделитесь.

Смежные вопросы