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 =
ServiceLocator.Current.GetInstance<IContentRepository>();
private void GetChildrenRecursive(ContentReference parent, List<IContent> list)
{
foreach (var child in _contentRepository.GetChildren<IContent>(parent))
{
list.Add(child);
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)
.Select(contentRepository.Get<IContent>)
.ToList();
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 :) )
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.
Hi
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);
});
}
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?