Wednesday, 21 August 2013

How to query all child objects of a list for matching entities?

How to query all child objects of a list for matching entities?

I'm a bit of a neophyte when it comes to LINQ and lambda expressions, I'm
hoping someone can help me out.
What I'm doing is creating an aggregate object from an ADO.NET
SqlDataReader with multiple data 'tables' in the response.
The recordsets look like this:
Foo
FooId
...other descriptive fields

Bar
BarId
FooId
...other descriptive fields

Baz
BazId
BarId
...other descriptive fields

I'm iterating through each data table, one at a time. After I've processed
the first table, I have all my "Foos", then the second one is the "Bars",
which I can associate to the "Foo" without any trouble. (a "Bar" can be
assigned to more than one Foo).
The object I'm hydrating is a List (for purposes of returning it via a web
service) and the objects look like this (pseudocode):
class Foo
{
int FooId
string Name
string etc
string YouGetTheIdea
List<Bar> Bars
}
class Bar
{
int BarId
string etc
List<Baz> Bazes
}
class Baz
{
int BazId
string etc
}
Up to this point, I'm fine. Where I get into trouble is that the "Bar"
objects have a list of "Baz" objects which can be attached to more than
one "Bar" (which in turn can be attached to more than one "Foo")
My code, thus far, looks something like this. If there's a better way to
approach this, please let me know. My trouble is that when I get to the
section dealing with "Baz," I'm not sure how to select all "Bar" objects
(under any Foo who has a Bar with that Id) so I can add the current BazId
to its list of Baz objects. What I have in here currently is blowing up at
runtime, so it's obviously not right.
using (SafeDataReader reader = this.ExecSPReader(SP_NAME, parms.ToArray()))
{
if (reader != null)
{
// deal with Foos
while (reader.Read())
{
Foo o = new Foo();
o.FooID = reader.GetInt64("FooID");
o.Etc = reader.GetString("etc");
//...more properties
fooList.Add(o);
}
// deal with Bars
reader.NextResult();
while (reader.Read())
{
Bar p = new Bar();
long BarFooID = reader.GetInt64("FooID");
p.BarID = reader.GetInt64("BarID");
//...more properties
// find Foo that has this Bar and add to it
Foo o = fooList.Find(x => x.FooID == barFooID);
if (o != null)
{
if (o.Bars == null)
{
o.Bars = new List<Bar>();
}
o.Bars.Add(p);
}
}
/*
***
*** Up to here, everything is fine
*** ...but now we need to assign the baz elements to bars, which can belong
*** to any/all Foos
***
*/
// deal with Bazs
reader.NextResult();
while (reader.Read())
{
long bazID = reader.GetInt64("BazID");
long barID = reader.GetInt64("BarID");
// here is the problem, ideally I'd like to get a list of all
Bar elements with
// the BarID from the datarow, but not sure how to do that --
the below foreach
// line errors at runtime
foreach(Bar p in fooList.Select(a => a.Bars.Where(b => b.BarID
== barID)))
{
if (p.Bazes == null)
{
p.Bazes = new List<Baz>();
}
p.Bazes.Add(bazID);
}
}
}
}
Greatly appreciate any help.

No comments:

Post a Comment