使用动态 linq 过滤对象列表
using dynamic linq to filter a list of objects
我有两个class这样的
public class Error{
public string Code{get;set;}
public string Description{get;set;}
}
public class Row{
public List<Error> Errors {get;set;}
....
}
因此,对于每一行,可能存在更多错误。
有可能使用动态 linq select 有错误代码的行(例如 Code1)?
所以,如果该行包含代码 1 和代码 2,我想要 select 该行。
如果在下面的示例中查询有一个行列表,我想要这样的查询
query.Where("Errors != null && Errors.Code.contains('Code1')")
使用linq的where扩展方法。并检查代码是否等于 Code1 或 Code2 并将结果转换为 Error
列表
List<Error> rows = row.Errors
.Where(x => x.Code == "Code1" && x.Code == "Code2")
.ToList();
或
var result = (from x in row.Errors
where x.Code == "Code1" && x.Code == "Code2"
select x).ToList();
IEnumerable<Row> rowCollection = ...; //your rows
var result = rowCollection
.Where(r => r.Code.Contains("Code1") && r.Code.Contains("Code2"))
.ToList();
我想这就是您要找的:
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)));
为了避免错误列表的空检查,我建议你在一个空的构造函数中初始化列表:
public Row()
{
Errors=new List<Error>();
}
您真正想要做的是使用类似 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);
}
It's possible using dynamic linq select the row that have an error code(for example Code1)?
据我了解,你有这样的东西
IQueryable<Row> query = ...;
string code = "Code1";
并且您需要以下静态查询的动态 LINQ 等效项:
var result = query
.Where(row => row.Errors != null && row.Errors.Any(error => error.Code == code));
因为在 Dynamic LINQ 中每个 Enumerable
扩展方法 lambda 进入一个单独的 "scope",里面的成员可以通过特殊的 it
标识符或根本没有标识符访问。它还允许您传递参数并使用 @p0
、@p1
等在查询字符串中通过索引引用它们
因此,上面的等效动态 LINQ 查询可能是这样的:
var result = query
.Where("Errors != null && Errors.Any(Code == @0)", code);
如果您想要 string.Contains
而不是完全匹配,只需将 Code == @0
替换为 Code.Contains(@p0)
。
当然你可以在里面嵌入字符串字面值,但要记住它需要用双引号括起来("
):
var result = query
.Where("Errors != null && Errors.Any(Code == \"Code1\")");
我有两个class这样的
public class Error{
public string Code{get;set;}
public string Description{get;set;}
}
public class Row{
public List<Error> Errors {get;set;}
....
}
因此,对于每一行,可能存在更多错误。 有可能使用动态 linq select 有错误代码的行(例如 Code1)?
所以,如果该行包含代码 1 和代码 2,我想要 select 该行。
如果在下面的示例中查询有一个行列表,我想要这样的查询
query.Where("Errors != null && Errors.Code.contains('Code1')")
使用linq的where扩展方法。并检查代码是否等于 Code1 或 Code2 并将结果转换为 Error
列表 List<Error> rows = row.Errors
.Where(x => x.Code == "Code1" && x.Code == "Code2")
.ToList();
或
var result = (from x in row.Errors
where x.Code == "Code1" && x.Code == "Code2"
select x).ToList();
IEnumerable<Row> rowCollection = ...; //your rows
var result = rowCollection
.Where(r => r.Code.Contains("Code1") && r.Code.Contains("Code2"))
.ToList();
我想这就是您要找的:
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)));
为了避免错误列表的空检查,我建议你在一个空的构造函数中初始化列表:
public Row()
{
Errors=new List<Error>();
}
您真正想要做的是使用类似 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);
}
It's possible using dynamic linq select the row that have an error code(for example Code1)?
据我了解,你有这样的东西
IQueryable<Row> query = ...;
string code = "Code1";
并且您需要以下静态查询的动态 LINQ 等效项:
var result = query
.Where(row => row.Errors != null && row.Errors.Any(error => error.Code == code));
因为在 Dynamic LINQ 中每个 Enumerable
扩展方法 lambda 进入一个单独的 "scope",里面的成员可以通过特殊的 it
标识符或根本没有标识符访问。它还允许您传递参数并使用 @p0
、@p1
等在查询字符串中通过索引引用它们
因此,上面的等效动态 LINQ 查询可能是这样的:
var result = query
.Where("Errors != null && Errors.Any(Code == @0)", code);
如果您想要 string.Contains
而不是完全匹配,只需将 Code == @0
替换为 Code.Contains(@p0)
。
当然你可以在里面嵌入字符串字面值,但要记住它需要用双引号括起来("
):
var result = query
.Where("Errors != null && Errors.Any(Code == \"Code1\")");