Copied to clipboard

Flag this post as spam?

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


  • M 40 posts 273 karma points
    Jun 01, 2016 @ 13:46
    M
    0

    Using variable for strongly typed where clause

    Hi,

    I've got a where clause that repeats a couple of times. I'd like to put it into a variable to make it easier to read and manage, but it throws an error when I try. Can anybody help?

    What I've got (working):

    @foreach (var L2page in L1page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)))
                        {//code here}
    

    What I'd like:

    var whereClause = "x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)";
    
    @foreach (var L2page in L1page.Children.Where(@whereClause))
    {//code here}
    

    The error I'm getting is:

    Umbraco.Core.Dynamics.ParseException: Expression expected
    

    Thanks

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jun 01, 2016 @ 13:50
    Jan Skovgaard
    0

    Hi M

    Not sure I know the solution to your problem but could you please add the error message you receive as well? That will make it much easier for people to try and help you out :)

    /Jan

  • M 40 posts 273 karma points
    Jun 01, 2016 @ 13:55
    M
    0

    Trying to do too many things at once! I've added the error message in the original post now.

    Thanks

  • Jordan 24 posts 182 karma points
    Jun 01, 2016 @ 14:22
    Jordan
    1

    Hey M,

    I don't believe that is possible, you are storing the where clause as a string, which will then be passed as a string inside the where().

    This means the code is processing it like so:

    L1page.Children.Where("x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)")
    

    rather then:

    L1page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias))
    

    its also worth noting that the @ is not needed in-front of the whereClause as it is running within a code block already. So you only need .Where(whereClause)

  • M 40 posts 273 karma points
    Jun 02, 2016 @ 10:03
    M
    0

    Thanks for your reply. I thought that might be the case.

    I'm trying a slightly different approach now.

    IEnumerable<IPublishedContent> whereClause;
    
    whereClause = L1page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias));
    
    @foreach (var L2page in whereClause)
        {//code here}
    

    This works for the top level, but I'd like to be able to change "L1page" to "L2page". I could do

    whereClause = L2page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias));
    

    But is there a more elegant way where I could just change the first bit? Maybe declare it as a list or something like that?

  • Jordan 24 posts 182 karma points
    Jun 02, 2016 @ 10:34
    Jordan
    0

    Hey M,

    That looks good. You could try something like this, I don't have the code in front of me to fully test it but I believe this should add each collection to a list of IEnumerable.

    List<IEnumerable<IPublishedContent>> whereClause = new List<IEnumerable<IPublishedContent>>();
    
    whereClause.Add(L1page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)));
    whereClause.Add(L2page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)));
    

    Let me know if that helps/works :).

    Thanks Jordan

  • M 40 posts 273 karma points
    Jun 02, 2016 @ 11:21
    M
    0

    Thanks Jordan. The problem I'm hitting now is L1page/L2page are out of context due to nesting.

    Looks like I'm stuck redeclaring the variable at each level i.e.

    IEnumerable<IPublishedContent> whereClause;
    
    whereClause = L1page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias));
    
    foreach (var L2page in whereClause)
        {
    whereClause = L2page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias));
    //code here
    }
    

    Thanks for your help

  • Jordan 24 posts 182 karma points
    Jun 02, 2016 @ 11:35
    Jordan
    0

    Ah I see what you mean.

    You could always do another lambda expression to get l2 pages. example.

    List<IEnumerable<IPublishedContent>> whereClause = new List<IEnumerable<IPublishedContent>>();
    
    //add level 1 content to list
    whereClause.Add(L1page.Children.Where(x => x.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)));
    
     //add level 2 content to list
    whereClause.Add(whereClause.First().Where(x => x.Children.Where(y => y.IsVisible() && !excludedDocTypes.Contains(x.DocumentTypeAlias)));
    

    not sure if that is useful at all, but may make code simpler.

    The code may need some tweaking as again I don't have VS in front of me to test it. But that should add the first l1page.Children to the list, and I think the whereClause.First() should grab the the l1page.Children from the list and then allow you to then return result for the level 2 page to be added back to the list.

    I am not sure the code can be nested like this though, so may be a case of moving the whereClause.First() out into another variable and then using that variable to grab the level 2 page content.

    Let me know if this helps at all.

Please Sign in or register to post replies

Write your reply to:

Draft