I’m writing some C#(.NET) to work with Umbraco 4.7 to import articles into a blog. In short, this algorithm is designed to cycle through every existing article and check whether it has the same ID as the new article that we’re attempting to pull in from an XML. The algorithm works alright, but I can’t help but think having four foreach loops is incredibly inefficient for what I’m doing.
foreach (Document yearNode in node.Children) //News > Years
{
foreach (Document monthNode in yearNode.Children) //Years > Months
{
foreach (Document dayNode in monthNode.Children) //Months > Days
{
foreach (Document newsItem in dayNode.Children) //Days > Articles
{
// If there isn't an ID match, go ahead and create a new article node.
}
That’s the basic algorithm without it’s main functionality, just the foreach loops. It’s a little more complicated than simply cycling through calendar dates because it’s more of a folder structure containing specific nodes. Would anyone be able to suggest a way of simplifying this at all?
Using the idea of getting all of your article node’s by
DocumentType, you could use an equivalent of this GetDescendants extension method to iterate through the nodes of a specific document type.That method is written specifically for NodeFactory’s
Nodeclass but can easily be rewritten forDocument. To use an extension method, you’ll need to create a new class and make it static. Example:And then to use the method in our context:
Note: I’m not sure why, but it seems that an
.OfType<Document>()or.Cast<Document>()is required after.GetDescendants(). (See edit below)It would be more efficient to use NodeFactory’s
Nodeas opposed toDocumentsince NodeFactory pulls it’s information from the XML cache and doesn’t make calls to the database each time likeDocumentdoes. The only drawback to using NodeFactory is that it only contains those nodes that have been published, but usually you’ll only want to work with those anyway. See Difference between Node and Document.Edit: After doing a little of tinkering, I discovered that
Documentalready includes aGetDescendants()method and that returns anIEnumerableand that’s why we have to do the.Cast<Document>(). So it looks like you can avoid having to create an extension method if you choose to still useDocument. Otherwise, should you still want to use something like the above extension method, you’ll need to rename it to something else.