A little background on the query below. Cell has a 1:M to Container and a 1:M with Printer. I want a query that will retrieve all Cells and associated containers, if they exist, and associated printers, if they exist. Essentially I want to do a left outer join on both tables. Here is the query I have:
var query = from cell in Cell
join container in Container.Where (row => row.SerialNumber == "1102141") on cell.CellID equals container.CellID
into containers
join printer in Printer.Where (row => ro开发者_JAVA百科w.Name == "PG10RelWarrPrt3") on cell.CellID equals printer.CellID
into printers
select new { Cell = cell, Containers = containers, Printers = printers };
query.Dump();
This query works, but is not efficient. It does a left outer join on Container, but, for each Cell, it performs a separate query to retrieve any Printer rows, instead of also doing a left outer join on Printer.
How can I change this so that it also does a left outer join on the Printer table? BTW, I want a hierarchical result set. IOW, each Cell should have a list of containers and a list of printers. Each would be empty of course, if none existed for the cell.
Here's a query to produce a flat result set with correct left joins.
var query = from cell in Cell
join container in Container.Where (row => row.SerialNumber == "1102141") on cell.CellID equals container.CellID
into containers
from container2 in containers.DefaultIfEmpty()
join printer in Printer.Where (row => row.Name == "PG10RelWarrPrt3") on cell.CellID equals printer.CellID
into printers
from printer2 in printers.DefaultIfEmpty()
select new { Cell = cell, Container = container2, Printer = printer2 };
You'll have to post-process the results locally to get the hierarchical shape desired.
If you write this post-processing code, you'll understand why linq to sql doesn't process multiple sibling collections for you.
To make this clearer, suppose you had 3 sibling collections.
If all three sibling collections were empty for some parent record, you'd have just the parent record 1 time with a bunch of nulls.
If all three sibling collections had 100 records for some parent record, you'd have 1 million rows, each with a copy of the parent record. Every child record would be duplicated 10,000 times in the result.
It's always important to keep in mind with any ORM that it generates sql and gets back flat result sets, no matter what hierarchically shaped result it eventually present you with.
It's usually wrong to use join
in LINQ to SQL.
Try:
var query = from cell in Cell
select new
{
Cell = cell,
Containers = cell.Containers
.Where (row => row.SerialNumber == "1102141"),
Printers = cell.Printers
.Where (row => row.Name == "PG10RelWarrPrt3")
};
精彩评论