我正在尝试将 Oracle Sql 查询转换为 Linq,但不确定如何继续。以下是 Sql 查询:
SELECT *
FROM CustomerShip,
(SELECT DISTINCT b.ShipSeq AS shipSeq
FROM Orders a,
CustomerShip b
WHERE a.OrderId IN (SELECT OrderId
FROM Orders
WHERE CustomerId = @CustomerId
AND OrderType <> 'A')
AND b.CustomerId = @CustomerId
AND b.ShipSeq = a.CustShip
AND OrderStatus <> 'C'
GROUP BY b.ShipSeq) i
WHERE CustomerId = @CustomerId
AND (Address NOT LIKE '%RETAIL%STORE%')
AND ShipSeq = i.ShipSeq(+)
ORDER BY ShipTo DESC, OrderDate DESC;
在转换为LINQ时,我尝试将其分解为三个单独的查询。
var query1 = from c in CustomerShip
where c.CustomerId == customerId
&& !c.Address.Contains("RETAIL")
&& !c.Address.Contains("STORE")
orderby c.ShipTo descending, c.OrderDate descending
select c;
var query2 = from o in Orders
where o.CustomerId == customerId
&& !o.OrderType.Equals("A")
select o.OrderId;
var query3 = (from o in Orders
from c in CustomerShip
where c.CustomerId == customerId
&& c.ShipSeq == o.CustShip
&& !o.OrderStatus.Equals("A")
select c.ShipSeq).Distinct();
现在我正在尝试将它们组合成一个查询,但不确定如何做。以下是我要走的方向:
var query = from c in CustomerShip
let subquery = from o in Orders
where o.CustomerId == customerId
&& !o.OrderType.Equals("A")
select o.OrderId
from or in model.Orders
where subquery.Contains(or.OrderId)
&& c.CustomerId == customerId
&& c.ShipSeq == or.CustShip
&& !or.OrderStatus.Equals("A")
group c by c.ShipSeq
into i
select c.ShipSeq
where c.CustomerId == customerId
&& !c.Address.Contains("RETAIL")
&& !c.Address.Contains("STORE")
orderby c.ShipTo descending, c.OrderDate descending
select c, i;
更新
我有一个查询,它基本上可以工作,但是执行时间几乎需要两分钟(相比于Oracle查询的0.02秒),而且结果的顺序不正确。有人看到我错过了什么吗?
var innerQuery = from x in model.Orders
where x.CustomerId == customerId
&& !x.OrderType.Equals("A")
select x.OrderId;
var result = from c in model.CustomerShip
join subQuery in
(
(from o in model.Orders
from c in model.CustomerShip
where c.CustomerId == customerId
&& innerQuery.Contains(o.OrderId)
&& !o.FLAG_ORD_STATUS.Equals("C")
&& c.ShipSeq == o.CustShip
select c.ShipSeq).Distinct()
) on c.ShipSeq equals subQuery into temp
from x in temp.DefaultIfEmpty()
where c.CustomerId == customerId
&& !c.Address.Contains("RETAIL")
&& !c.Address.Contains("STORE")
orderby c.ShipTo descending, c.OrderDate descending
select c;
AND ShipSeq = i.ShipSeq(+)
。这是Oracle特有的吗? - PixelPaul(+)
是 Oracle 表示外连接的旧方式。这里的意思是“所有客户记录,加上与 ShipSeq 匹配的内部查询记录。详情请见:https://dev59.com/NWw15IYBdhLWcg3whMI1”。 - James Curran