user3401335
user3401335

Reputation: 2405

using dynamic linq to filter a list of objects

I have two class like this

public class Error{
   public string Code{get;set;}
   public string Description{get;set;}
}

public class Row{
   public List<Error> Errors {get;set;}
   ....
}

So, for each row, can exists more errors. It's possible using dynamic linq select the row that have an error code(for example Code1)?

So, if the row contains Code1 and Code2, i want select the row.

if in the example below query has a list of rows i want a query like this

query.Where("Errors != null && Errors.Code.contains('Code1')")

Upvotes: 1

Views: 4675

Answers (5)

Ivan Stoev
Ivan Stoev

Reputation: 205629

It's possible using dynamic linq select the row that have an error code(for example Code1)?

The way I understand it, you have something like this

IQueryable<Row> query = ...;
string code = "Code1";

and you want the Dynamic LINQ equivalent of the following static query:

var result = query
   .Where(row => row.Errors != null && row.Errors.Any(error => error.Code == code));

Since in Dynamic LINQ every Enumerable extension method lambda enters a separate "scope", the members inside are accessible through special it identifier or no identifier at all. Also it allows you to pass parameters and refer to them inside the query string by index using @p0, @p1 etc.

Hence the equivalent Dynamic LINQ query of the above could be like this:

var result = query
    .Where("Errors != null && Errors.Any(Code == @0)", code);

If instead of exact match you want string.Contains, simply replace Code == @0 with Code.Contains(@p0).

Of course you could embed the string literal value inside, but keep it mind it requires to be surrounded with double quotation marks ("):

var result = query
    .Where("Errors != null && Errors.Any(Code == \"Code1\")");

Upvotes: 4

James Curran
James Curran

Reputation: 103515

What you really want to do is to use something like the PredicateBuilder: http://www.albahari.com/nutshell/predicatebuilder.aspx

IQueryable<Error> SearchProducts(Row row, string[] codes, string[] keywords)
{
    var predicate = PredicateBuilder.False<Error>();

    foreach (string code  in codes)
    {
        string temp = code;
        predicate = predicate.Or(p => p.Code.Contains(temp));
    }
    foreach (string keyword in keywords)
    {
        string temp = keyword;
        predicate = predicate.Or(p => p.Description.Contains(temp));
    }
    return row.Errors.AsQueryable().Where(predicate);
}

Upvotes: 1

Timon Post
Timon Post

Reputation: 2889

Use the where extension method of linq. and check if the code is equals to Code1 or Code2 and convert the result into list of Error

 List<Error> rows = row.Errors
            .Where(x => x.Code == "Code1" && x.Code == "Code2")
            .ToList();

OR

var result = (from x in row.Errors
            where x.Code == "Code1" && x.Code == "Code2"
            select x).ToList();

Upvotes: 0

ocuenca
ocuenca

Reputation: 39326

I think this is what you are looking for:

var codes=new List<string>{"Code1","Code2"}; 
// given a list of codes you want those rows that contains all codes
var result= rows.Where(r=> codes.All(c=>r.Errors.Any(e=>e.Code==c)));

To avoid the null checking of the error list, I suggest you initialize the list in an empty constructor:

public Row()
{
   Errors=new List<Error>();
}

Upvotes: 1

Alexander
Alexander

Reputation: 9632

IEnumerable<Row> rowCollection = ...; //your rows
var result = rowCollection
    .Where(r => r.Code.Contains("Code1") && r.Code.Contains("Code2"))
    .ToList();

Upvotes: 0

Related Questions