Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
405 views
in Technique[技术] by (71.8m points)

c# - Dynamic filtering using Linq

I have a List<Device>. In the Device class there are 4 properties, namely Name, OperatingSystem, Status and LastLoggedInUser. I need to write a method:

IQueryable<Device> FilterDeviceList(
    List<Device> Devices,
    List<string> filter,
    string filterValue)

where filter will contain options for filtering "name", "os" to indicate the fields to include in the search. If "all" is passed then all 4 fields need to be included. filtervalue will contain the value to be filtered like "windows", "Calvin".

Can anyone suggest a method to achieve this?

Edit:

If I was not clear, I am doing the filtering somewhat like this, it is the commented part for which I need the code.

if(filter.contains(name))
{
//filter with name
}
if( filter.contains(both name and os)
{
// I only need the filter value to contain in name or OS (only needed in any one of the field,not necessary to be in both)

}`
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could build your query as follows:

private static IQueryable<Device> FilterDeviceList(List<Device> devices, Device device)
{
    var query = devices.AsQueryable();

    if (device.Name != null)
        query = query.Where(d => d.Name == device.Name);

    if (device.OS != null)
        query = query.Where(d => d.OS == device.OS);

    if (device.Status != null)
        query = query.Where(d => d.Status == device.Status);

    if (device.LastLoggedInUser != null)
        query = query.Where(d => d.LastLoggedInUser == device.LastLoggedInUser);

    return query;
}

Then you can call this function with a device object. I.e. if you want name to be included, just pass a device object with a name (leave other properties to their default value). If you want everything to be included, pass in a device object with everything filled in:

var r = FilterDeviceList(devices, new Device
            {
                Name = "yourFilterValue",
                OS = "yourFilterValue",
                LastLoggedInUser = "yourFilterValue",
                Status = "yourFilterValue"
            });

Edit, filter on name property:

var r = FilterDeviceList(devices, new Device
                {
                    Name = "yourFilterValue"
                });

Edit 2, take a look at predicatebuilder

var predicate = PredicateBuilder.False<Device>();

if(document.Name != null)
    predicate = predicate.Or(d => d.Name == document.Name);

if(document.OS != null)
    predicate = predicate.Or(d => d.OS == document.OS);

return devices.Where(predicate);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...