Copied to clipboard

Flag this post as spam?

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


  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 15:13
    Rob
    0

    Help with a dynamic query in where clause UMBRACO 7 Razor

    Having trouble creating a dynamic query within umbraco. Razor

    Thought I had it but I think I am missing something fundamental.

    Any help would be appreciated or a different approach.

    Basically I have a set of products that may or may not have selected items in a multipicker.

    Just accessing one item would be simple enough.

    var collection = CurrentPage.Children("product").Where("visible").Where("subscriptionOptions.Contains(@0)", "1234")

    But I would like to dynamically generate that last where. and came up with this.

    listValues = listValues.TrimEnd(",");
    
        int counter = 0;
        var dynamicQueryIn = "";    
        var dynamicQueryOut = "";
        var dynamicQuery = "";
    
            foreach(var lv in resultsList){
    
            if (string.IsNullOrEmpty(dynamicQueryOut)){
            dynamicQueryOut = string.Format("\""+lv+"\"");
            }else{
            dynamicQueryOut += string.Format(",\""+ lv +"\"");
            }       
    
            if (string.IsNullOrEmpty(dynamicQueryIn)){
            dynamicQueryIn = string.Format("subscriptionOptions.Contains(@0)");
            }else{
            dynamicQueryIn += string.Format(" && subscriptionOptions.Contains(@"+@counter+")");
            }       
             counter++;
            }
    
    
        dynamicQuery = string.Format("\""+dynamicQueryIn+"\","+dynamicQueryOut);
    

    The final result looks exactly as I want it when i simple render

    @dynamicQuery

    to the page it looks for example like this.

    "subscriptionOptions.Contains(@0) && subscriptionOptions.Contains(@1) && subscriptionOptions.Contains(@2) && subscriptionOptions.Contains(@3)","1568","1634","1576","1581"
    

    But when I call.

     var collection = CurrentPage.Children("product").Where("visible").Where(dynamicQuery)
    

    I get

    Exception Details: Umbraco.Core.Dynamics.ParseException: Expression of type 'Boolean' expected

    Any ideas...

    btw I am a long time user but can't log in on my usual username as the password reset on our.umbraco seem borked.

    Kind Regards

    Rob

  • Alex Skrypnyk 6175 posts 24186 karma points MVP 8x admin c-trib
    Nov 10, 2016 @ 15:42
    Alex Skrypnyk
    1

    Hi Rob,

    Lets rewrite this code to strongly typed?

    What do you think?

    Just provide code of all file and we will do it together, don't like to use dynamics sorry.

    Thank,

    Alex

  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 15:53
    Rob
    0

    Well this is this the bit I am working on.

    What it is supposed to do it look at a node called product then look in the subscriptionOptions of that node which is a multipicker

    and see if the listValues passed from the previous page are there listValues is passed initiall as say...

    1234,1235,1236,

    I strip of the last , leaving it as

    "1234,1235,1236"

    Which is then turned into a list or rather in this case var called resultsList

     @{
            listValues = listValues.TrimEnd(",");
    var resultsList = listValues.Split(',');
            int counter = 0;
            var dynamicQueryIn = "";    
            var dynamicQueryOut = "";
            var dynamicQuery = "";
        foreach(var lv in resultsList){
                if (string.IsNullOrEmpty(dynamicQueryOut)){
                dynamicQueryOut = string.Format("\""+lv+"\"");
                }else{
                dynamicQueryOut += string.Format(",\""+ lv +"\"");
                }       
                if (string.IsNullOrEmpty(dynamicQueryIn)){
                dynamicQueryIn = string.Format("subscriptionOptions.Contains(@0)");
                }else{
                dynamicQueryIn += string.Format(" && subscriptionOptions.Contains(@"+@counter+")");
                }       
                 counter++;
                }
            dynamicQuery = string.Format("\""+dynamicQueryIn+"\","+dynamicQueryOut);
            var collection = CurrentPage.Children("product").Where("visible").Where(dynamicQuery);
        foreach(var id in collection)
            {<p>@id</p>}
    
        }
    
  • Alex Skrypnyk 6175 posts 24186 karma points MVP 8x admin c-trib
    Nov 10, 2016 @ 16:17
    Alex Skrypnyk
    1

    Hi again Rob,

    var listValues = "1234,1235,1236";
    var resultsList = listValues.Split(',').Select(int.Parse);
    
    var collection = Umbraco.AssignedContentItem.Children.Where(x => x.IsVisible()).Where(x => x.GetPropertyValue<int[]>("subscriptionOptions").Intersect(resultsList).Any());
    
    foreach (var id in collection)
    {
        <p>@id</p>
    }
    

    Look please at my code example, I used totally strongly typed variables and linq Intersect method for finding common items in 2 arrays.

    Can you test it and give me feedback?

    Thanks,

    Alex

  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 16:31
    Rob
    0

    Hi not sure here...

    I pasted it in the bit and it gave me.

    Value cannot be null. Parameter name: first

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.ArgumentNullException: Value cannot be null. Parameter name: first

    Source Error:

    So I substituted

    Umbraco.AssignedContentItem for CurrentPage and I get

    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

    Compiler Error Message: CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type

    Source Error:

    Line 112:var resultsList = listValues.Split(',').Select(int.Parse); Line 113: Line 114:var collection = CurrentPage.Children.Where(x => x.IsVisible()).Where(x => x.GetPropertyValue

  • Alex Skrypnyk 6175 posts 24186 karma points MVP 8x admin c-trib
    Nov 10, 2016 @ 16:34
    Alex Skrypnyk
    1

    Try this line:

    var collection = Umbraco.AssignedContentItem.Children.Where(x => x.IsVisible()).Where(x => x.GetPropertyValue<string>("subscriptionOptions").Split(',').Select(int.Parse).Intersect(resultsList).Any());
    
  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 18:36
    Rob
    0

    Sorry for the late response. Hell of a commute.

    I am getting

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    Source Error:

    Line 112:var resultsList = listValues.Split(',').Select(int.Parse); Line 113: Line 114:var collection = Umbraco.AssignedContentItem.Children.Where(x => x.IsVisible()).Where(x => x.GetPropertyValue

  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 19:22
    Rob
    0

    Ok I changed it to...

    var collection = Umbraco.AssignedContentItem.Children.Where(x => x.IsVisible()).Where(x => x.DocumentTypeAlias == "subscribeProduct").Where(x => x.GetPropertyValue<string>("subscriptionOptions").Split(',').Select(int.Parse).Intersect(resultsList).Any());
    

    And made sure all subscribeProduct pages have at least one value in subscriptionOptions

    It returns all 7 products.. regardless of the values in subscribeOptions

  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 20:05
    Rob
    1

    Ok I have narrowed down what's happening and still need a little help.

    the subscriptionProduct must have ALL listItems present within the multipicker subscriptionOptions

    So a product1 would have say 1111,2222,3333,4444,5555,6666,7777 in its subscription options

    product2 perhaps 1111,2222,3333,4444,5555

    and product3 1111,3333,4444,5555

    if listItems is say 1111,2222,3333,4444

    only product 1 and 2 would be returned to the collection.

    your help so far seems to be acting like or rather than and

    I hope I have explained it better this time :)

    Thankyou so much for you help so far.

  • Alex Skrypnyk 6175 posts 24186 karma points MVP 8x admin c-trib
    Nov 10, 2016 @ 22:05
    Alex Skrypnyk
    1

    Rob, great description of task !!!

    I hope I wil help you to solve the issue.

    Thanks,

    Alex

  • Alex Skrypnyk 6175 posts 24186 karma points MVP 8x admin c-trib
    Nov 10, 2016 @ 21:57
    Alex Skrypnyk
    100

    Hi Rob,

    Now it's more clear, last code snipped found even one common id.

    This code will find children with all resultsList ids:

    var collection = Umbraco.AssignedContentItem.Children.Where(x => x.IsVisible()).Where(x => x.GetPropertyValue<int[]>("subscriptionOptions").Intersect(resultsList).Count() == resultsList.Count());
    

    Thanks,

    Alex

  • Rob 22 posts 133 karma points
    Nov 10, 2016 @ 22:44
    Rob
    0

    Thanks Alex, your last post put me on the right track.

    I added in the DocumentTypeAlias (as there are other unlrelated children without the subsriptionOptions field) and used the syntax of your previous post plus the intersect of the last post and came up with this.

    var collection = Umbraco.AssignedContentItem.Children.Where(x => x.IsVisible()).Where(x => x.DocumentTypeAlias == "subscribeProduct").Where(x => x.GetPropertyValue<string>("subscriptionOptions").Split(',').Select(int.Parse).Intersect(resultsList).Count() == resultsList.Count());
    

    Which appears to work. I will put some more tests intomorrow as it's getting late but it looks perfect.

    Thanks so much for your help with this and the time you have taken to assist.

    Kind Regards Rob

Please Sign in or register to post replies

Write your reply to:

Draft