Reputation: 2405
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
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
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
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
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
Reputation: 9632
IEnumerable<Row> rowCollection = ...; //your rows
var result = rowCollection
.Where(r => r.Code.Contains("Code1") && r.Code.Contains("Code2"))
.ToList();
Upvotes: 0