Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

Does GetDescendents hit the cache?


Does GetDescendents hit the cache before going to the DB? I've found a few articles/blog posts that claim it doesn't, but they're all pre-7.x, and I can't find anything more recent to debunk them.

If it does hit the cache, is there any performance or technical reason to use GetDescendents vs calling GetChildren recursively?

Jun 09, 2014 19:14

Hi Joseph,

GetDescendents will also hit the cache.

On my machine, both GetDescendents and GetChildren take 52-56 ms (approx  2 000 pages).

GetChildren does have a slightly better "cold start".

Solution with GetChildren:

private readonly IContentRepository _contentRepository =

private void GetChildrenRecursive(ContentReference parent, List<IContent> list)
    foreach (var child in _contentRepository.GetChildren<IContent>(parent))
        GetChildrenRecursive(child.ContentLink, list);

public void Test()
    var list = new List<IContent>();

    var sw = Stopwatch.StartNew();
    GetChildrenRecursive(ContentReference.StartPage, list);
    var elapsedTime = sw.ElapsedMilliseconds;

Solution with GetDescendents:

public void Test()
    var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();

    var sw = Stopwatch.StartNew();
    var list = contentRepository.GetDescendents(ContentReference.StartPage)
    var elapsedTime = sw.ElapsedMilliseconds;

GetDescendets returns only ContentReference(s) and cannot filter pages by type. If you don't need to filter descendants by type, I guess that GetDescendets is more readable than recursive function (or maybe not :) )

Edited, Jun 10, 2014 10:10

The issue with GetDescendents and doing a GetPage for each can mean quite alot of work for you. Though the GetItems that takes an IEnumerable<ContentReference> method found on DataFactory through the might help you out a little to batch the contentloading up.

Jun 10, 2014 21:31


If you use the right functions there should be a preformance gain by using

var allPages=EPiServer.DataFactory.Instance.GetItems(EPiServer.DataFactory.Instance.GetDescendents(PageReference.StartPage),LanguageSelector.MasterLanguage())
This will use methods
GetItems => LoadBatched => GetScatteredContents => LoadContents (from DefaultContentProvider) =>
this._contentListDBAccessor().LoadSpecificContentInstances(contentLinks, languageBranchID);
That function will load alll not previsue loaded items in one go from the database.

public IList<IContent> LoadSpecificContentInstances(int[] contentLinks, int languageBranchID)
return base.Database.Execute<IList<IContent>>(delegate
DbCommand dbCommand = this.CreateCommand("netPageListPaged");
byte[] array = new byte[4 * contentLinks.Length];
int num = 0;
int[] contentLinks2 = contentLinks;
for (int i = 0; i < contentLinks2.Length; i++)
int num2 = contentLinks2[i];
array[num++] = (byte)(num2 >> 24 & 255);
array[num++] = (byte)(num2 >> 16 & 255);
array[num++] = (byte)(num2 >> 8 & 255);
array[num++] = (byte)(num2 & 255);
dbCommand.Parameters.Add(this.CreateParameter("Binary", DbType.Binary, ParameterDirection.Input, array));
dbCommand.Parameters.Add(this.CreateParameter("Threshold", Settings.Instance.StringDelayedLoadThreshold));
dbCommand.Parameters.Add(this.CreateParameter("LanguageBranchID", DbType.Int32, ParameterDirection.Input, languageBranchID));
return this.ReadPageList(dbCommand);

Jun 18, 2014 18:06
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.