Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • mike 90 posts 258 karma points
    Mar 03, 2015 @ 04:16
    mike
    0

    Get Children in One Line?

    Is there anyway to get all the children of an item as an IEnumerable in one statement?

    For instance this is my code:

    int totalPages = (count - 1) / pageSize + 1;
    int start = (page - 1) * pageSize + 1;
    
    IPublishedContent ipc = Umbraco.Content(contentId);
    
    IEnumerable<IPublishedContent> news = ipc.Children
        .Where(x => x.ContentType.Alias == "NewsItem")
        .OrderByDescending(x => x.CreateDate)
        .Skip(start)
        .Take(pageSize);

     

    Thats making 2 calls.  I did some googling and found a forum post that said Umbraco supports linq queries on dynamic objects as text so I tried:

    IEnumerable<IPublishedContent> news = Umbraco.Content(contentId).Children
        .Where("ContentType.Alias == \"NewsItem\"")
        .OrderByDescending("CreateDate")
        .Skip(start.ToString())
        .Take(pageSize.ToString());

     

    I've played around with the second one a bit but keep getting errors,  This one generates error because it doesnt have a definition of orderbydescending.

    Anyone know the correct sytax to get that to work?

     

  • Mikkel Holck Madsen 7 posts 159 karma points hq
    Mar 03, 2015 @ 09:00
    Mikkel Holck Madsen
    0

    Hi Mike What do you mean by thats two calls? The second one does the same right? you just didnt add the Children to a local variable.

    Couldnt you just do it as

    IEnumerable<IPublishedContent> news = Umbraco.Children.Where(x => x.ContentType.Alias == "NewsItem").OrderByDescending(x => x.CreateDate).Skip(start).Take(pageSize)

  • mike 90 posts 258 karma points
    Mar 03, 2015 @ 15:35
    mike
    100

    Hi Mikkel.

    This:

    IPublishedContent ipc =Umbraco.Content(contentId);

    Makes a call to the cache to create the parent object that I don't need, just for the sake of being used as a reference in the next statement.  I don't really know much about how the Umbraco cache works yet but if this was linq to sql then it would be generating two SQL queries when one should be sufficient.

    Your example doesnt work as needs the content method but lets say you called it "Umbraco.Content(id).Children.Where..." then it would return a dynamic object that to my understanding does not support linq querying.

    To get round this Umbraco has added extension methods that allow us to pass Linq queries as text strings.  I have only found brief documentation on this, look under complex querying here - https://our.umbraco.org/Documentation/Reference/Mvc/querying ;

    After a good nights sleep I figured out it was not returning an IEnumerableit was actually returning DynamicPublishedContentList. I was still confused though as it didnt contain definition for OrderByDescendng but after checking the code for the OrderBy method - https://github.com/umbraco/Umbraco-CMS/blob/ded1def8e2e7ea1a4fd0f849cc7a3f1f97cd8242/src/Umbraco.Web/Dynamics/Grouping.cs

    I could see it just looks for "desc" or "descending" at the end of the string.

    So the final working statement is:

    DynamicPublishedContentList news = Umbraco.Content(contentId).Children
        .Where("ContentType.Alias == \"NewsItem\"")
        .OrderBy("CreateDate desc")
        .Skip(start)
        .Take(pageSize);

    I must admit I do not know how this all comes together under the hood.  Is a dynamic query worse performance that a strongly typed query?  Is there a way I am missing to do this as a strongly typed query in one statement?

    I realise I am being pedantic but I like to be confident I am doing things the right way.

     ** EDIT **

    Been googling and it seems it is recommended to always query in strongly typed way.  So original way with 2 calls is the best?

    ** EDIT **

    Ahh, I have been very silly.  There is seperate method to return typed content.  Query should be:

    IEnumerable<IPublishedContent> news = Umbraco.TypedContent(contentId).Children
                        .Where(x => x.ContentType.Alias == "NewsItem")
                        .OrderByDescending(x => x.CreateDate)
                        .Skip(start)
                        .Take(pageSize);

    Oh well, I am learning slowly but surely.

Please Sign in or register to post replies

Write your reply to:

Draft