假设我们有一个Person对象的集合
class Person
{
public string PersonName {get;set;}
public string PersonAddress {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
并在代码定义集合中的某处
List<Person> pesonsList = new List<Person>();
Run Code Online (Sandbox Code Playgroud)
我们需要一个过滤器,需要过滤集合并将结果返回给最终用户.假设我们有一个Filter类型对象的集合
class Filter
{
public string FieldName {get;set;}
public string FilterString {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
在我们的代码中的某个地方
List<Filter> userFilters = new List<Filter>();
Run Code Online (Sandbox Code Playgroud)
因此,我们需要通过userFilters集合中定义的过滤器来过滤personsList集合的内容.凡Filter.FieldName == "PERSONNAME" || Filter.FieldName =="PersonAddress".我怎样才能以酷炫的方式使用LINQ呢?像switch这样的解决方案,或者我认为,personList上的扩展方法可以从FiledName确定要查看的Person的属性.别的什么?有点棘手:)谢谢.
Rub*_*ben 10
您可以构建lambda表达式以使用Expression该类创建正确的谓词.
public static Expression<Func<TInput, bool>> CreateFilterExpression<TInput>(
IEnumerable<Filter> filters)
{
ParameterExpression param = Expression.Parameter(typeof(TInput), "");
Expression lambdaBody = null;
if (filters != null)
{
foreach (Filter filter in filters)
{
Expression compareExpression = Expression.Equal(
Expression.Property(param, filter.FieldName),
Expression.Constant(filter.FilterString));
if (lambdaBody == null)
lambdaBody = compareExpression;
else
lambdaBody = Expression.Or(lambdaBody, compareExpression);
}
}
if (lambdaBody == null)
return Expression.Lambda<Func<TInput, bool>>(Expression.Constant(false));
else
return Expression.Lambda<Func<TInput, bool>>(lambdaBody, param);
}
Run Code Online (Sandbox Code Playgroud)
使用此辅助方法,您可以在任何IQueryable<T>类上创建扩展方法,因此这适用于每个LINQ后端:
public static IQueryable<T> Where<T>(this IQueryable<T> source,
IEnumerable<Filter> filters)
{
return Queryable.Where(source, CreateFilterExpression<T>(filters));
}
Run Code Online (Sandbox Code Playgroud)
...你可以像这样打电话:
var query = context.Persons.Where(userFilters);
Run Code Online (Sandbox Code Playgroud)
如果您还想支持IEnumerable<T>集合,则需要使用此额外的扩展方法:
public static IEnumerable<T> Where<T>(this IEnumerable<T> source,
IEnumerable<Filter> filters)
{
return Enumerable.Where(source, CreateFilterExpression<T>(filters).Compile());
}
Run Code Online (Sandbox Code Playgroud)
请注意,这仅适用于字符串属性.如果要对字段进行过滤,则需要更改Expression.Property为Expression.Field(或MakeMemberAccess),如果需要支持除字符串属性之外的其他类型,则必须为方法的Expression.Constant某个部分提供更多类型信息CreateFilterExpression.
| 归档时间: |
|
| 查看次数: |
12835 次 |
| 最近记录: |