Nhibernate 交易日最后4家供应商的产品

Nhibernate 交易日最后4家供应商的产品,nhibernate,subquery,queryover,correlated-subquery,Nhibernate,Subquery,Queryover,Correlated Subquery,嗨,我有这个sql,必须翻译成NHibernate QueryOver SELECT S.Number, S.Description, S.BrandDescription, subquery.vendornumber, subquery.vendorname FROM Stocks.Stock S left join (select vendorNumber, VendorName, POLID, LastTransactionDate from

嗨,我有这个sql,必须翻译成NHibernate QueryOver

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中将子查询用作派生表。如果你有建议,请分享


谢谢

我一直在研究这个问题,发现如果想完全使用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)
var库存供应商=
Session.QueryOver(()=>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()
.选择列表(
lst=>
lst.SelectGroup(()=>V.Name)。带别名(()=>svhModal.VendorName)
.SelectGroup(()=>V.Number)。带别名(()=>svhModal.VendorNumber)
.SelectGroup(()=>sstk.Number)。带别名(()=>svhModal.StockNumber)
.Select(projects.Max(()=>V.TransactionDate)).with别名(()=>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>();
var stockDetail=Session.QueryOver(()=>stk)
.何处(索尼克里特里亚)
.SelectList(list=>list
.选择(()=>stk.Id)。使用别名(()=>sdrmodel.Id)
。选择(()=>stk.Number)。使用别名(()=>sdrmodel.Number)
.TransformUsing(Transformers.AliasToBean())
.List();
IList vlst2=null;
IList newStock=新列表();
这里启动两个循环,用每个库存及其供应商列表中的5个顶级供应商填充列表对象。从查询的Stockdetail结果循环,从筛选的供应商结果到外部循环stockid的内部循环,仅在循环中获取前5个供应商,完成后将结果返回报告。工作正常

foreach(StockDetail中的StockDetail ostk)
{
stkid=ostk.编号;
vlst2=(从stockVendors中的v开始,其中v.StockNumber==stkid orderby v.LastTransactionDate降序选择v);
vndrcnt=0;
stok=新库存详细信息
{
Id=ostk.Id,
编号=ostk.Number,
////其他领域也在这里
};
if(vlst2.Count()==0)
{
添加(stok);
}
foreach(vlst2中的库存供应商vn)
{
如果(vndrcnt==0)
{
stok.VendorName=vn.VendorName;
stok.VendorNumber=vn.VendorNumber;
//这里的其他领域。。。
添加(stok);
}
其他的
{
newStock.Add(新股票详细信息)
{
Id=ostk.Id,
编号=ostk.Number,
VendorName=vn.VendorName,
VendorNumber=vn.VendorNumber,
//在库存记录中添加供应商信息。
});
}
vndrcnt++;
如果(vndrcnt>=4)
打破
}

这解决了我的问题,并且在调查了许多天之后实现了这一点。您可能会找到更好的方法,因此请分享。

简单地说,NHibernate FROM是通过类/实体映射定义的,JOIN是通过引用映射定义的。因此上述SQL查询将无法工作。这里的解决方案是:1)创建视图-并封装所有的复杂性-将其映射为实体2)使用原始SQL查询来获取这些数据。任何其他解决方案都不适合通用ORM感谢@RadimKöhler的回复。我已经完成了一个存储过程,该过程工作正常,但由于安全限制,我的老板拒绝NHibernate映射实体之外的任何事情。我还尝试创建两个单独的查询结果并合并或联接以满足此要求。有什么想法或建议吗?我会尝试使用任何一个视图,然后将其映射为实体,或者使用一些“C#”组合-正如你所说的。但问题是,你必须创建的这种复杂查询超出了ORM世界的能力范围…抱歉,没有更好的答案…再次感谢。至少我可以向我的老板和团队展示这个回复,他们认为NHibernate中的一切都是可能的,而且比SQL简单得多。我是唯一的p这里的erson可以编写复杂的SQL,这对我来说是个大问题。
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;
                }