2017-08-02 38 views
0

我試圖將下面的Oracle Sql查詢轉換爲linq,但沒有取得太大的成功。我不知道如何處理AND ShipSeq = i.ShipSeq(+),我知道這是在Oracle中的LEFT OUTER JOIN。我在LinqPad中測試下面的Linq查詢,在那裏我沒有得到任何語法錯誤,但是它在執行查詢時出錯。有任何想法嗎?將具有左外部聯接的Oracle SQL查詢轉換爲Linq

的Oracle 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 query = from s in CustomerShip 
      join m in Orders on s.ShipTo equals m.ShipTo into temp 
      from x in temp.DefaultIfEmpty() 
      where (from o in Orders 
        from c in CustomerShip 
        where (from x in CustomerOrders 
          where x.CustomerId == customerId 
          && !x.OrderType.Equals("A") 
          select x.OrderId).Contains(o.OrderId) 
        && c.CustomerId == customerId 
        && c.ShipTo == o.ShipTo 
        && !o.OrderStatus.Equals("C") 
        select c.ShipTo).Distinct().Contains(s.ShipTo) 
      && s.CustomerId == customerId 
      && !s.Address.Contains("RETAIL") 
      && !s.Address.Contains("STORE") 
      orderby s.ShipTo descending, s.OrderDate descending 
      select s; 
+0

這可能有助於(https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b)有一個部分上加入 –

回答

0

我認爲直譯是這樣的:

var iQuerySub = from o in Orders where o.CustomerId == pCustomerId && o.OrderType != "A" select o.OrderId; 

var iQuery = (from a in Orders 
       from b in CustomerShip 
       where iQuerySub.Contains(a.OrderId) && 
       b.CustomerId == pCustomerId && 
       b.ShipSeq == a.CustShip && 
       a.OrderStatus != "C" 
       group b by b.ShipSeq into bg 
       select new { shipSeq = bg.Key }).Distinct(); 

var ans = from s in CustomerShip 
      where s.CustomerId == pCustomerId && 
      (!s.Address.Contains("RETAIL") || !s.Address.Contains("STORE") || s.Address.IndexOf("RETAIL") > s.Address.IndexOf("STORE")) 
      join i in iQuery on s.ShipSeq equals i.shipSeq into ij 
      from i in ij.DefaultIfEmpty() 
      orderby s.ShipTo, s.OrderDate descending 
      select new { s, shipSeq = (i != null ? i.shipSeq : (int?)null) }; 

然而無論是SQL和LINQ似乎ineffi cient給我,但沒有領域知識,這是所有我可以優化:

var iQuery2 = (from b in CustomerShip 
       where b.CustomerId == pCustomerId && 
       Orders.Any(a => a.CustomerId == pCustomerId && a.OrderType != "A" && a.OrderStatus != "C" && b.ShipSeq == a.CustShip) 
       select new { shipSeq = b.ShipSeq }).Distinct(); 

var ans2 = from s in CustomerShip 
      where s.CustomerId == pCustomerId && 
      (!s.Address.Contains("RETAIL") || !s.Address.Contains("STORE") || s.Address.IndexOf("RETAIL") > s.Address.IndexOf("STORE")) 
      join i in iQuery2 on s.ShipSeq equals i.shipSeq into ij 
      from i in ij.DefaultIfEmpty() 
      orderby s.ShipTo, s.OrderDate descending 
      select new { s, shipSeq = (i != null ? i.shipSeq : (int?)null) }; 
+0

謝謝你的努力。您的答案几乎適用於我,但在'iQuery'查詢中,我在LinqPad中測試時遇到錯誤:'不是GROUP BY表達式' – PixelPaul

+0

我想我已經確定了這個問題,但不知道如何更正。當我查看生成的SQL時,它有一個「GROUP BY b.ShipSeq」,但查詢的第一行是'SELECT b.ShipSeq,c.OrderId'。不知道爲什麼'c.OrderId'在select語句中? – PixelPaul

+0

這可能是LINQ爲了處理需要'OrderId'的'where iQuerySub.Contains'而如何實現'iQuerySub'。我在一個匿名對象模型的LINQPad中運行了這個,但是顯然我沒有真正的數據庫甚至模式,所以我不確定我的模型是否正確 - 在翻譯時我不得不猜測哪些表的某些列屬於沒有方案或明確的別名表達。 – NetMage