DefaultIfEmpty in LINQ-to-SQL join causing duplicates
Here is an extract of my 开发者_JAVA百科query:
...
join p in dc.PODs on c.ID equals p.Consignment into pg
from pgg in pg.DefaultIfEmpty()
...
What the query should do is get all the 'PODs' associated with a consignment, store it as an IEnumerable object (which seems to work) so I can run through it when querying the main IEnumerable generated from the query.
The problem is, I am getting duplicate main rows with the DefaultIfEmpty line, which only happens when a row has multiple PODs - so it's returning a row for each POD, which is incorrect. If I take out the pg.DefaultIfEmpty() line, it seems to work a bit better, but I still want to get the rows without PODs.
Any ideas guys?
Just want to confirm for your 2nd case, wouldn't the output be without the Two, Four, Five which have none item since it is not an outer join?
One
1 TextBox
Three
3 Refridgerator
3 Bucket
What I tried was use an equivalent WHERE IN for dc.PODS.
....join appraisal in ef_appraisal on application.a_appraisalid equals appraisal.a_appraisalid
where
(from r in ..
select r.r_applicationid).Contains(application.a_id) )
Do share if you have other ideas
Forgive me if I'm off on your intention because I can't see the complete structure of your data or your initial from
or final select
clause in your query excerpt. So I'm posting what I think is a solution based on your snippet and sample data I constructed. Let me know if I'm off and I'll correct it.
If you want a list of rows of consignments to PODs, with each consignment to POD on its own line, you could do something like this (keep in mind my from
and select
clause are based on my sample data):
// select the consignment id & name (i made up) and each matching POD
var results = from c in consignments
join p in dc.PODs on c.ID equals p.Consignment into pg
from pgg in pg.DefaultIfEmpty()
select new { ID = c.ID, Name = c.Name, POD = pgg };
// This is just a SAMPLE display just for kicks and grins
foreach (var r in results)
{
Console.WriteLine(r.Name + " " + ((r.POD != null)
? (r.POD.Consignment + " " + r.POD.Description)
: "none"));
}
This query outputs something like:
One 1 TextBox
Two none
Three 3 Refridgerator
Three 3 Bucket
Four none
Five none
However I'm not quite sure I understand your remark:
"The problem is, I am getting duplicate main rows"
I'm not sure if you're saying you don't want to see the one consignment per purchase per row where each result in the IEnumerable
is an item with the consignment and a sequence of PODs, you'd want a query like:
// select the Consignment ID and Name (i made up), and list of PODs
// instead of the individual POD
var results = from c in consignments
join p in dc.PODs on c.ID equals p.Consignment into pg
select new { ID = c.ID, Name = c.Name, PODs = pg };
// This is just a SAMPLE display just for kicks and grins
foreach (var r in results)
{
Console.WriteLine(r.Name + " ");
if (r.PODs.Count() > 0)
{
foreach (var pod in r.PODs)
{
Console.WriteLine("\t" + pod.Consignment + " " + pod.Description);
}
}
else
{
Console.WriteLine("\tNone");
}
}
Where the select is selecting the POD list instead of the individual match, which outputs like this:
One
1 TextBox
Two
None
Three
3 Refridgerator
3 Bucket
Four
None
Five
None
精彩评论