2010-05-18 49 views
2

給定一個Orders的經典DB結構有零個或多個OrderLines,而OrderLine只有一個Product,我該如何編寫一個LINQ查詢來表示這個?如何讓linq主詳細查詢0..n關係?

輸出將

OrderNumber - OrderLine - Product Name 
Order-1  null  null // (this order has no lines) 
Order-2  1   Red widget 

我嘗試這樣做查詢,但不能動線

var model = (from po in Orders 
      from line in po.OrderLines 
       select new 
       { 
        OrderNumber = po.Id, 
        OrderLine = line.LineNumber, 
        ProductName = line.Product.ProductDescription, 
       } 
      ) 
+0

這應該「從PO訂單」讀(即定購變量,而不是常規的類型) – 2010-05-18 04:27:11

回答

4

Here is an article這似乎解釋瞭如何實現正是你正在嘗試做的獲取訂單。

public static void OuterJoinSimpleExample() 
{ 
    var customers = new List<Customer>() { 
     new Customer {Key = 1, Name = "Gottshall" }, 
     new Customer {Key = 2, Name = "Valdes" }, 
     new Customer {Key = 3, Name = "Gauwain" }, 
     new Customer {Key = 4, Name = "Deane" }, 
     new Customer {Key = 5, Name = "Zeeman" } 
    }; 

    var orders = new List<Order>() { 
     new Order {Key = 1, OrderNumber = "Order 1" }, 
     new Order {Key = 1, OrderNumber = "Order 2" }, 
     new Order {Key = 4, OrderNumber = "Order 3" }, 
     new Order {Key = 4, OrderNumber = "Order 4" }, 
     new Order {Key = 5, OrderNumber = "Order 5" }, 
    }; 

    var q = from c in customers 
      join o in orders on c.Key equals o.Key into outer 
      from o in outer.DefaultIfEmpty() 
      select new { 
       Name = c.Name, 
       OrderNumber = ((o == null) ? "(no orders)" : o.OrderNumber) 
      }; 

    foreach (var i in q) { 
     Console.WriteLine("Customer: {0} Order Number: {1}", 
      i.Name.PadRight(11, ' '), i.OrderNumber); 
    } 

    Console.ReadLine(); 
} 
+1

+1它被稱爲外部加入。 – 2010-05-18 03:57:58

+0

我在這裏用Google搜索「LINQ INNER JOIN」(doh!)。可以使用join和defaultifempty()嗎?我看到這個博客文章說這不是一個好主意:http://blogs.teamb.com/craigstuntz/2010/01/13/38525/(但他沒有給出一個外部連接的例子) – 2010-05-18 04:09:54

+0

這是很多好的使用' DefaultIfEmpty()'只要有一個默認值不會破壞你的解決方案的語義。 – 2010-05-18 04:38:17

0

這是工作查詢(使用上面鏈接的例子內置):

var model = (from po in orders 
      join line in orderLines // note this is another var, it isn't po.Lines 
      on po.Id equals line.OrderId into g 
      from line in g.DefaultIfEmpty() 
      select new 
      { 
       OrderNumber = po.Id, 
       OrderLine = line == null ? 0 : line.LineNumber, 
       ProductName = line == null ? string.Empty : line.Product.ProductDescription, 
      } 
     ) 
0
var model = 
    from po in Orders 
    from line in po.OrderLines.DefaultIfEmpty() 
    select new 
    { 
    OrderNumber = po.Id, 
    OrderLine = line != null ? 
     (int?)line.LineNumber : null, 
    ProductName = line != null ? 
     line.Product.ProductDescription : null 
    } ;