开发者

How to make linq master detail query for 0..n relationship?

Given a classic DB structure of Orders has zero or more OrderLines and OrderLine has exactly one Pro开发者_开发知识库duct, how do I write a LINQ query to express this?

The output would be

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

I tried this query but is not getting the orders with no lines

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


Here is an article which appears to explain how to achieve exactly what you are trying to do.

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();
}


This is the working query (built using the example linked above):

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,
            }
         )


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 
  } ;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜