gregor.tusar
02/11/2025, 12:52 PMvar config = umbracoHelper.ContentAtRoot().DescendantsOrSelfOfType(MySpecialConfiguration.ModelTypeAlias).FirstOrDefault() as MySpecialConfiguration;
I know that there is only one config of this type so FirstOrDefault()
is not problematic here. Is traversing the tree like that very consuming? Is it the correct way of getting the config ?RHamilton
02/11/2025, 2:53 PMvar rootNodes = umbracoHelper.ContentAtRoot();
EDIT - I just went and looked closer at DescendantsOrSelfOfType and you can indeed call it on a collection. I didn't think that was valid - thanks for showing me that 😀
depending on your configuration, and how much you mind (or don't mind) scoping in your query, you could start with a known node. So for example here is one of my site's root nodes.
so when I call ContentAtRoot() I'm going to get the 5 root nodes (not recycle bin). But if I know I'm looking for maybe a Promo Code I might start with the settings node and traverse my way down from there
var storeSettings = umbracoHelper.ContentAtRoot().FirstOrDefault(x => x.ContentType.Alias == "storeProductSettings");
This eliminates the need to traverse all of the nodes, so faster, but might be a bit hardcoded for your taste. If you would rather look everywhere you could try something like this
var specificNode = rootNodes
.SelectMany(root => root.DescendantsOrSelf())
.FirstOrDefault(node => node.ContentType.Alias == MySpecialConfiguration.ModelTypeAlias);
(.SelectMany(root => root.DescendantsOrSelf()) ensures that you traverse all descendants from each root node.)
Let me know if this gets you going or if I can be of any further help
-Roger
https://cdn.discordapp.com/attachments/1338855214995738667/1338885595518337024/image.png?ex=67acb5e1&is=67ab6461&hm=e32eddbe957b13ebf02724098bbeb01aadd6ceb38cd1f5815c713b6b83bf66f0&
https://cdn.discordapp.com/attachments/1338855214995738667/1338885595904086016/image.png?ex=67acb5e1&is=67ab6461&hm=4eebbda7ffebdd697379859888eadfbfbf266d30050e8fe3e3e7ce5430cd3040&gregor.tusar
02/12/2025, 10:19 AM.SelectMany(root => root.DescendantsOrSelf())
is not really needed here. Right ?
My question is if this approach is not too much time consuming and if I should use IPublishedContentQuery
and after I get GUID and then I should get only that from UmbracoHelper.
https://cdn.discordapp.com/attachments/1338855214995738667/1339179135053991946/image.png?ex=67adc742&is=67ac75c2&hm=c219fada7a9a1655a3296cbe0af25b8327c03a2a75a932557577b85c8f06108e&Mike Chambers
02/12/2025, 5:45 PMMike Chambers
02/12/2025, 5:48 PMMike Chambers
02/12/2025, 5:51 PMRHamilton
02/12/2025, 6:48 PMJason
02/12/2025, 10:04 PM.Descendant<T>()
.
Swapping to .Children.FirstOrDefault(x=> x is MyContentType)
was 100x faster, and that was by no means a big site.
Note that I didn't use .FirstChild<T>()
which also iterates all the children before returning the first of those that has the type 😬Jason
02/12/2025, 10:23 PMSander L
02/13/2025, 6:45 AMgregor.tusar
02/13/2025, 10:30 AMStopwatch sw = Stopwatch.StartNew();
var config = umbracoHelper.ContentAtRoot().DescendantsOrSelfOfType(MySpecialConfiguration.ModelTypeAlias).FirstOrDefault() as MySpecialConfiguration;
Console.WriteLine($"content at root descendatas {sw.ElapsedMilliseconds} ms : {config?.Id}");
sw.Restart();
var config2 = umbracoHelper.ContentAtRoot().First()?.FirstChild<ConfigurationFolder>()?.Descendant<MySpecialConfiguration>();
Console.WriteLine($"content at first child descendatas {sw.ElapsedMilliseconds} ms: {config2?.Id}");
content at root descendatas 7 ms : 7358
content at first child descendatas 7 ms: 7358
content at root descendatas 3 ms : 7358
content at first child descendatas 2 ms: 7358
content at root descendatas 6 ms : 7358
content at first child descendatas 9 ms: 7358
I did a little test with two approaches, but the results are not very telling 🙂Jason
02/13/2025, 10:55 PMumbracoHelper.ContentAtRoot().DescendantsOrSelfOfType(MySpecialConfiguration.ModelTypeAlias).FirstOrDefault()
vs
Umbraco.ContentAtRoot().FirstOrDefault().FirstChild<ConfigurationFolder>().FirstChild<MySpecialConfiguration>();
Or even
Umbraco.ContentAtRoot().FirstOrDefault().Children.FirstOrDefault(x => x is ConfigurationFolder).Children.FirstOrDefault(x => x is MySpecialConfiguration);
Assuming MySpecialConfiguration lives directly underneath ConfigurationFolder that is.
I went from something like the top, to the something like the bottom line and went from about 500μs to about 5μs per call (and our site called it a LOT).Sander L
02/14/2025, 7:50 PMSander L
02/14/2025, 7:51 PMMike Chambers
02/14/2025, 8:25 PM