Search code examples
c#.netstringumbracopredicatebuilder

PredicateBuilder: OR condition nested inside .And()


I'm using PredicateBuilder to build a query against a List of Umbraco Nodes to filter search results. I have the searched ID value coming through as a String via the QueryString which I then compare to a string field on each of the Umbraco Nodes in the list to get matches.

Currently, the code does the match against the target field in there is a value in the Query String which works fine. I need to add a conditional inside my .And() that tries to match the QS against the field String if the field has a value, but if the field has no value, then it should match that as well.

    if (!string.IsNullOrEmpty(qsId))
    {
       predicate = predicate.And(i => 
       Regex.IsMatch(i.GetProperty("makeTag").Value.ToString(), "\\b" + 
       qsId + "\\b"));
    }

I tried the following but it didn't seem to work properly:

    if (!string.IsNullOrEmpty(qsId))
    {
       predicate = predicate.And(i => 
       Regex.IsMatch(i.GetProperty("makeTag").Value.ToString(), "\\b" + 
       qsId + "\\b") || 
       string.IsNullOrEmpty(i.GetProperty("makeTag")).Value.ToString());
    }

Any ideas about what I'm doing incorrectly or perhaps a better way to approach this?


Solution

  • for nesting or in and, you can:

    create the or first, then and the or:

    if (!string.IsNullOrEmpty(qsId))
    {
        // default false
            var inner = PredicateBuilder.False<Product>();
    
        // first or
        inner = inner.Or (i => 
               Regex.IsMatch(i.GetProperty("makeTag").Value.ToString(), "\\b" + 
               qsId + "\\b");
    
        // second or       
        inner = inner.Or (i => 
            string.IsNullOrEmpty(i.GetProperty("makeTag")).Value.ToString());
    
    
        predicate = predicate.And(inner);
    }       
    

    below was my original answer, did not relaize need nested or in and


    original answer

    If I understand you correctly, you are trying to achieve (when hard coding it):

    Where(i => 
       Regex.IsMatch(i.GetProperty("makeTag").Value.ToString(), "\\b" + 
       qsId + "\\b" ||  string.IsNullOrEmpty(i.GetProperty("makeTag")).Value.ToString())
    

    if so, then using predicate builder, it should do it like:

    if (!string.IsNullOrEmpty(qsId))
    {
    
        // default false
        var predicate = PredicateBuilder.False<Product>();
    
        // first or
        predicate = predicate.Or (i => 
               Regex.IsMatch(i.GetProperty("makeTag").Value.ToString(), "\\b" + 
               qsId + "\\b");
    
        // second or       
        predicate = predicate.Or (i => 
            string.IsNullOrEmpty(i.GetProperty("makeTag")).Value.ToString());
    }
    

    more example of prediccate builder, check out: http://www.albahari.com/nutshell/predicatebuilder.aspx