tags:

views:

50

answers:

1

Hi,

I've seen a lot of questions on self-referencing tables in Linq2Sql and how to eagerly load all child records for a particular root object. I've implemented a temporary solution by accessing all underlying properties, but you can see that this doesn't do the performance any good.

The thing is though, that all records are correlated with each-other using a correlation GUID. Example below:

RootElement
- Id: 1
- ParentId: null
- CorrelationId: 4D68E512-4B55-44f4-BA5A-174B630A03DD

ChildElement1
- Id: 2
- ParentId: 1
- CorrelationId: 4D68E512-4B55-44f4-BA5A-174B630A03DD

ChildElement2
- Id: 3
- ParentId: 2
- CorrelationId: 4D68E512-4B55-44f4-BA5A-174B630A03DD

ChildElement1
- Id: 4
- ParentId: 2
- CorrelationId: 4D68E512-4B55-44f4-BA5A-174B630A03DD

In my case, I do have access to the correlationId, so I can retrieve all of my records by performing the following query:

from element in db.Elements
where element.CorrelationId == '4D68E512-4B55-44f4-BA5A-174B630A03DD'
select element;

But, of course, I want these elements associated with each other by executing this query:

from element in db.Elements
where element.CorrelationId == '4D68E512-4B55-44f4-BA5A-174B630A03DD' && element.ParentId == null
select element;

My question is: is it possible to combine the results the first query as some sort of 'caching mechanism' for the query where I get the root element?

Thanks for the input.

J.

A: 

I'm not quite clear on what you're trying to do, or what you mean by 'caching mechanism'. How does the second query create any sort of association?

My first hunch is that you want to group the results by parent, in which case you can simply call GroupBy(x => x.ParentId) on the results of the first query.

My second hunch is that your second query is to get only the root elements, in which case you just call Where(x => x.ParentId == null) on the results of the first query.

Please clarify further if this is not what you're looking for.

edit:

In response to your first comment, here is how to execute the two queries:

var correlated_elements = db.Elements.Where(element => element.CollelationId == '4D68E512-4B55-44f4-BA5A-174B630A03DD');
var root_elements = correlated_elements.Where(element => element.ParentId == null);

This is only going to make one query to the database. Still, your second query does not create a hierarchy -- it just returns the elements without a ParentId. If you can describe the hierarchy you want, we can work on a query to achieve it.

If you're not sure what queries are actually being executed against the database, you can output the SQL to the console or use a trial version of LINQ-to-SQL Profiler.

Jay
By 'caching mechanism' I mean that I want to use the results of the first query in the second query. In the first query I get a non-hierarchical list of all items with the same CorrelationId. It would be great if I could use this data to fill in the hierarchical structure of query 2 without Linq having to lazily fetch the data every time I access a child property. Any ideas?
J-Man
@J-Man Please see edit to my answer.
Jay
Ok, thanks Jay.I indeed tested the scenario you describe and whilst it does generate only one query, I still -like you said- don't get the hierarchy in my structure. Which is logical, I guess.The problem is that I don't know how deep my hierarchy will go. That's why I want Linq to eagerly load all of the child elements by default, without having to pass over them myself.I'm getting the feeling that it's just not technically possible. Any idea if this self-referencing recursiveness would work in Entity Framework (3.5-4.0)?
J-Man