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
} ;
精彩评论