Home > Mobile >  Linq Dynamic Query Issue - Operator '&&' incompatible with operand types 'String'
Linq Dynamic Query Issue - Operator '&&' incompatible with operand types 'String'

Time:09-29

I have a method which genere form me qeury. It's look like this:

        private static string PrepareWhereClause(string[] columns)
    {
        var query = $"({string.Join(" OR ", columns?.Select(c => $"{c} != null AND {c}.ToLower().Contains(@0)"))})";
        return query;
    }

This query is use on Where extension from Linq Dynamic like this:

public static IQueryable<T> Search<T>(this IQueryable<T> queryable, string phrase, params string[] columns) =>
        queryable?.Where(PrepareWhereClause(columns), phrase.ToLower());

My object what is inside query it's:

public class ResponsibilitiesWebDto
{
    public Guid Id { get; set; }
    public DictionaryBaseDto ResponsibilityType { get; set; }
    public UserForDetailedDto Employee { get; set; }
    public SupplierForDetailedDto Supplier { get; set; }
}

On argument for PrepereWhereClause are field of type string which are inside in ResponsibilityType, Employee and Supplier.

Query what it's generate by PrepereWhereClause is:

(ResponsibilityType.Name != null AND ResponsibilityType.Name.ToLower().Contains(@0) OR Employee.EmployeeId != null AND Employee.EmployeeId.ToLower().Contains(@0) OR Employee.Name != null AND Employee.Name.ToLower().Contains(@0) OR Employee.LastName != null AND Employee.LastName.ToLower().Contains(@0) OR Supplier.AccountNum != null AND Supplier.AccountNum.ToLower().Contains(@0) OR Supplier.Name != null AND Supplier.Name.ToLower().Contains(@0))

All it's ok when ALL childs element are not null. Problem is when some of them are null. I looking to this post on SO Dynamic Linq Core OrderBy Nullable Child Property and on issue on github and i try use but it's isn't work :( I modyfied my query to someone of this:

     private static string PrepareWhereClause(string[] columns)
    {
        var query = $"({string.Join(" OR ", columns?.Select(c => $"{c} != null AND {c}.ToLower().Contains(@0)"))})";
        var query1 = $"({string.Join(" OR ", columns?.Select(c => "(("   ConvertToNullableNested(c)   $") AND {c}.ToLower().Contains(@0))"))})";
        var query2 = $"({string.Join(" OR ", columns?.Select(c => $"np({c} != null AND {c}.ToLower().Contains(@0)"))})";
        var query3 = $"({string.Join(" OR ", columns?.Select(c => $"(np({c}) AND {c}.ToLower().Contains(@0))"))})";
        var query4 = $"({string.Join(" OR ", columns?.Select(c => $"(np({c}) && {c}.ToLower().Contains(@0))"))})";
        return query4;
    }

New Query is:

((np(ResponsibilityType.Name) && ResponsibilityType.Name.ToLower().Contains(@0)) OR (np(Employee.EmployeeId) && Employee.EmployeeId.ToLower().Contains(@0)) OR (np(Employee.Name) && Employee.Name.ToLower().Contains(@0)) OR (np(Employee.LastName) && Employee.LastName.ToLower().Contains(@0)) OR (np(Supplier.AccountNum) && Supplier.AccountNum.ToLower().Contains(@0)) OR (np(Supplier.Name) && Supplier.Name.ToLower().Contains(@0)))

But all the time i get error:

Operator '&&' incompatible with operand types 'String' and 'Boolean'

I try change && to AND but nothing change. What am I doing wrong?

I change query like @orxanmuv write but i still get error:

Query for it:

(((np(ResponsibilityType.Name) == null or np(ResponsibilityType.Name)) AND ResponsibilityType.Name.ToLower().Contains(@0)) OR ((np(Employee.EmployeeId) == null or np(Employee.EmployeeId)) AND Employee.EmployeeId.ToLower().Contains(@0)) OR ((np(Employee.Name) == null or np(Employee.Name)) AND Employee.Name.ToLower().Contains(@0)) OR ((np(Employee.LastName) == null or np(Employee.LastName)) AND Employee.LastName.ToLower().Contains(@0)) OR ((np(Supplier.AccountNum) == null or np(Supplier.AccountNum)) AND Supplier.AccountNum.ToLower().Contains(@0)) OR ((np(Supplier.Name) == null or np(Supplier.Name)) AND Supplier.Name.ToLower().Contains(@0)))

Error: {"Operator 'or' incompatible with operand types 'Boolean' and 'String'"}

CodePudding user response:

np method should be correct solution for Order By. For Where clause you have to check nulls in whole property path.

private static string PrepareWhereClause(string[] columns) => $"({string.Join(" OR ", columns?.Select(c => BuildLinqExpressionForNestedObject($"{c} != null AND {c}.ToLower().Contains(@0)", c)))})";

private static string BuildLinqExpressionForNestedObject(string propertyExpression, string propertyName)
{
    var propertyPath = propertyName.Split(".");
    if (propertyPath.Length > 1)
    {
        List<string> nullChecks = new List<string>();
        for (int i = 0; i < propertyPath.Length - 1; i  )
        {
            var nullCheck = $"{string.Join(".", propertyPath.Take(i   1))} != null";
            nullChecks.Add(nullCheck);
        }
        return $"({string.Join(" AND ", nullChecks)} AND {propertyExpression})";
    }
    return $"({propertyExpression})";
}

It will generate null checks on whole path to the nested property. Regards

  • Related