如何在LINQ中过滤具有不同参数的列表 [英] How to filter a list with varying parameters in LINQ
问题描述
假设我有一个这样的课程:
Suppose I have a class like this:
public class SampleClass
{
public string SampleProperty1 { get; set; }
public string SampleProperty2 { get; set; }
public string SampleProperty3 { get; set; }
public string SampleProperty4 { get; set; }
public string SampleProperty5 { get; set; }
}
我有一个这样的列表:
List<SampleClass> sampleList = new List<SampleClass>();
我想按SampleProperty1
和SampleProperty5
过滤该列表.下次,我将使用SampleProperty3
或SampleProperty2
.我的意思是用户可以按自己想要的任何属性进行过滤.
I want to filter that list by SampleProperty1
and SampleProperty5
. Next time I will use SampleProperty3
or SampleProperty2
. I mean user can filter by any property he wants.
如何实现这种灵活性?
我不想写if语句和属性一样多,因为属性的实际数量更多.
I don't want to write if statements as many as properties because the real number of properties is a lot more.
有一种聪明的方法吗?
谢谢.
推荐答案
您可以为每个属性构建lambda表达式,并使用它过滤集合.
假设您有Dictionary
个属性名称,以及要用于过滤的属性值:
You can build lambda expression for each property and filter the collection with it.
Let's say you have Dictionary
of property names with their values you want to filter by:
var filters = new Dictiontionary<string, object>();
IEnumerable<SampleClass> query = listOfSampleClasses;
// we will loop through the filters
foreach(filter in filters)
{
// find the property of a given name
var property = typeof(SampleClass).GetProperty(filter.Key, BindingFlags.Instance | BindingFlags.Public);
if (property == null) continue;
// create the ParameterExpression
var parameter = Expression.Parameter(typeof(SampleClass));
// and use that expression to get the expression of a property
// like: x.SampleProperty1
var memberExpression = Expression.Property(parameter, property);
// Convert object type to the actual type of the property
var value = Convert.ChangeType(filter.Value, property.PropertyType, CultureInfo.InvariantCulture);
// Construct equal expression that compares MemberExpression for the property with converted value
var eq = Expression.Equal(memberExpression, Expression.Constant(value));
// Build lambda expresssion (x => x.SampleProperty == some-value)
var lambdaExpression = Expression.Lambda<Func<SampleClass, bool>>(eq, parameter);
// And finally use the expression to filter the collection
query = query.Where(lambdaExpression);
}
var filteredList = query.ToList();
当然,您可以将该代码放入通用方法中,并过滤任何类型的集合.
Of course, you can put that code inside a generic method and filter collection of any type.
对于输入字典,包含两对:"SampleProperty1" - "foo"
和"SampleProperty2" - "bar"
它将产生类似这样的内容:
For input dictionary, containing two pairs: "SampleProperty1" - "foo"
and "SampleProperty2" - "bar"
It will produce something like that:
listOfSampleClasses
.Where(x => x.SampleProperty1 == "foo")
.Where(x => x.SampleProperty2 == "bar");
这篇关于如何在LINQ中过滤具有不同参数的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!