Returning a list of IContent items with a grand child item containing a known property.
Hi All,
I am trying to get my head around how to return an IEnumerable list of IContent items ( e.g. both published and un-published items ) where one of the grand child items has a known property.
E.g.
If we have the following structure:
Building > Floor > Room
And the Room node has a property called " Number of Chairs "
I want to get a list of all Building's where the is at least one Room with 5 chairs.
As mentioned above this needs to be both Published and Un-published items, hence I cannot do an XPATH query on the published nodes.
I think you should be able to do this with the IContentService. The IContentService has methods like GetDescendants(int nodeId) with an overload, which takes an IContent. This gets the descendant IContents of a current IContent.
So, bascially:
var contentService = ApplicationContext.Services.ContentService;
var rootContent = contentService.GetById(1234) // should not be hardcoded, this is just for having a starting point.
var rooms = contentService.GetDescendants(rootContent).Where(x => x.ContentType.Alias.Equals("room") && HasProperty("numberOfChairs) && x.GetValue<int>("numberOfChairs") > 5);
Things to note about this:
the GetDescendants() call can be slow if there's a lot of child (and sub-child) nodes in the tree.
using the IContentService performs database calls, afaik (correct me if I'm wrong here) which also is not very performant. However, it's needed to get the unpublished nodes aswell.
An alternative is the method GetContentOfContentType(int id) method on the IContentService, but this should only ever be used if you are certain you want all nodes of a given type. I.e., this might not be the case when running multilingual sites.
TypedContent returns an IPublishedContent, which only works for published nodes, Chris said he needs published and unpublished, so this won't work for his scenario.
I presume it needs to be the structure that you said because there are pages for each of Building > Floor > Room ?
My answer if not would be to store all the data on the Building node but I guess you're stuck with that structure.
If not, how about using Examine to search the Room nodes and then when you have the result display the Parent.Parent or if thats not possible with IContent (not done much with it sorry) you could query the path put that into a comma separated array and go 2 levels up.
Sorry if I've misunderstood any of your requirement!
Just edited my answer above to filter out the doc types. I fully admit that Ben Howarth's answer is more readable and I really like the way he thought about it the other way round but my answer'll work just as well :)
Thank you all for your replies, in the end I actually ended up using Jule's solution hence I marked it as the solution, however I think Ben Howarth also provided a good solution as well.
I have not had the chance to test if one out performs the other, maybe if I ever get some spare time I will test it.
Thanks again for all your quick responses and for Richard Terris... you can have a half ;-)
Returning a list of IContent items with a grand child item containing a known property.
Hi All,
I am trying to get my head around how to return an IEnumerable list of IContent items ( e.g. both published and un-published items ) where one of the grand child items has a known property.
E.g.
If we have the following structure:
Building > Floor > Room
And the Room node has a property called " Number of Chairs "
I want to get a list of all Building's where the is at least one Room with 5 chairs.
As mentioned above this needs to be both Published and Un-published items, hence I cannot do an XPATH query on the published nodes.
Cheers, Chris
Hiya Chris,
I think you should be able to do this with the
IContentService
. TheIContentService
has methods likeGetDescendants(int nodeId)
with an overload, which takes anIContent
. This gets the descendantIContent
s of a currentIContent
.So, bascially:
Things to note about this:
GetDescendants()
call can be slow if there's a lot of child (and sub-child) nodes in the tree.IContentService
performs database calls, afaik (correct me if I'm wrong here) which also is not very performant. However, it's needed to get the unpublished nodes aswell.An alternative is the method
GetContentOfContentType(int id)
method on theIContentService
, but this should only ever be used if you are certain you want all nodes of a given type. I.e., this might not be the case when running multilingual sites.Hope this helps any :-)
All the best,
Bo
Hi Chris,
You could do something like:
/Michael
TypedContent returns an IPublishedContent, which only works for published nodes, Chris said he needs published and unpublished, so this won't work for his scenario.
Caveat emptor: this will be DB-heavy, but should do the trick.
Hi Chris,
I presume it needs to be the structure that you said because there are pages for each of Building > Floor > Room ?
My answer if not would be to store all the data on the Building node but I guess you're stuck with that structure.
If not, how about using Examine to search the Room nodes and then when you have the result display the Parent.Parent or if thats not possible with IContent (not done much with it sorry) you could query the path put that into a comma separated array and go 2 levels up.
Sorry if I've misunderstood any of your requirement!
Ben
Hi All,
I think you must all be thirsty, I mentioned beer on twitter and this thread just lit up :-)
Thank you all for your replies, really appreciated.
I think Benjamin Howarth has quite possibly hit the nail on the head, I will give it a go and get back to the thread shortly.
Cheers, Chris
Possibly not that performant with lots of nodes
You didn't say 'correctly answering' so can I just get a beer?
Just edited my answer above to filter out the doc types. I fully admit that Ben Howarth's answer is more readable and I really like the way he thought about it the other way round but my answer'll work just as well :)
J
Hi All,
Thank you all for your replies, in the end I actually ended up using Jule's solution hence I marked it as the solution, however I think Ben Howarth also provided a good solution as well.
I have not had the chance to test if one out performs the other, maybe if I ever get some spare time I will test it.
Thanks again for all your quick responses and for Richard Terris... you can have a half ;-)
Cheers,
Chris
is working on a reply...