Reputation: 41
I have a class structure as follows below (there can be any number of each subclass and there can also be multiple Masters). I want use a linq query to get a flattened list of Subfolios, filtered by the “Index ” property of Subfolio.
I think I can get the Subfolios by Master using either:
IEnumerable< Subfolio> result = from dd in devices.Master
where dd.ID == 14
from pfo in dd. Portfolio
from folio in pfo.Folio
from subfolio in folio.Subfolio
where subfolio.Ind == 32
select subfolio;
Or
IEnumerable<Subfolio> result =
devices.master.Where(x => x.ID == 14)
.SelectMany(y => y.PFO)
.SelectMany(z => z.Folio)
.SelectMany(a => a.Subfolio)
.Where(b=>b.Ind==32);
I could do the same for each slave and combine the results with the Master query, but is there a way of doing this in one linq operation. At the moment I am using a large nest of foreach loops, which is very clunky.
The simplified Class structure is:
Devices
Master
Portfolio
Folio
Subfolio
Subfolio
Folio
Subfolio
Subfolio
Subfolio
Portfolio
Folio
Subfolio
Subfolio
Folio
Subfolio
Subfolio
Subfolio
Slave
Portfolio
Folio
Subfolio
Subfolio
Folio
Subfolio
Subfolio
Subfolio
Portfolio
Folio
Subfolio
Subfolio
Folio
Subfolio
Subfolio
Subfolio
Slave
Portfolio
Folio
Subfolio
Subfolio
Folio
Subfolio
Subfolio
Subfolio
Portfolio
Folio
Subfolio
Subfolio
Folio
Subfolio
Subfolio
Subfolio
Upvotes: 0
Views: 1134
Reputation: 41
Further to above, this is my full solution (I didn't make it clear that Slaves are a subclass of Masters)
public nF GetValuebyuNidIndex(dev devices, UInt32 MuNID, ushort nFIndex)
{
var result_m = devices.wNode.Where(p => p.uNID == MuNID)
.SelectMany(x => x.PFO);
var result_s = devices.wNode.Where(p => p.uNID == MuNID)
.SelectMany(x => x.sNode)
.SelectMany(x => x.PFO);
var combined = result_m.Union(result_s)
.SelectMany(x => x.Folio)
.SelectMany(x => x.nF)
.Where(x => x.Ind == nFIndex);
return combined.FirstOrDefault();
}
This also works. Presumably it compiles to the same thing?
public nF GetValuebyuNidIndex1(dev devices, UInt32 MuNID, ushort nFIndex)
{
var result_m = from dd in devices.wNode
where dd.uNID == MuNID
from pfo in dd.PFO
select pfo;
var result_s = from dd in devices.wNode
where dd.uNID == MuNID
from snode in dd.sNode
from pfo in snode.PFO
select pfo;
var combined = result_m.Union(result_s);
var result = from cc in combined
from ff in cc.Folio
from nn in ff.nF
where nn.Ind == nFIndex
select nn;
return result.FirstOrDefault();
}
Upvotes: 0
Reputation: 11058
Not sure if this code will work (testing would take time), but something like that should do the trick:
var resultMaster = devices.Master.SelectMany(y => y.PFO);
var resultSlave = devices.Slave.SelectMany(y => y.PFO);
var result = resultMaster.Union(resultSlave)
.SelectMany(z => z.Folio)
.SelectMany(a => a.Subfolio)
.Where(b=>b.Ind==32);
It's 3 parts for readability, but the query will be executed as one.
Upvotes: 1