使用Linq进行动态过滤
我有一个List
。 在Device
类中有4个属性,即Name
, OperatingSystem
, Status
和LastLoggedInUser
。 我需要写一个方法:
IQueryable FilterDeviceList( List Devices, List filter, string filterValue)
其中filter
将包含用于过滤"name"
, "os"
选项,以指示要包含在搜索中的字段。 如果传递"all"
则需要包括所有4个字段。 filtervalue
将包含要过滤的值,如"windows"
, "Calvin"
。
谁能建议一种方法来实现这一目标?
编辑:
如果我不清楚,我做的过滤有点像这样,它是我需要代码的注释部分。
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) }`
您可以按如下方式构建查询:
private static IQueryable FilterDeviceList(List 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; }
然后,您可以使用设备对象调用此函数。 即如果你想要包含名称,只需传递一个带有名称的设备对象(将其他属性保留为默认值)。 如果您希望包含所有内容,请传入设备对象,其中包含所有内容:
var r = FilterDeviceList(devices, new Device { Name = "yourFilterValue", OS = "yourFilterValue", LastLoggedInUser = "yourFilterValue", Status = "yourFilterValue" });
编辑,过滤名称属性:
var r = FilterDeviceList(devices, new Device { Name = "yourFilterValue" });
编辑2,看看谓词构建器
var predicate = PredicateBuilder.False(); 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);
你可以这样做:
public IEnumerable FilterDevices(IEnumerable devices, IEnumerable> filters, string filterValue) { foreach (var filter in filters) { devices = devices.Where(d => filter(d).Equals(filterValue)); } return devices; }
附:
public class Device { public string Name { get; set; } public string OS { get; set; } }
用法:
var devices = new List { new Device { OS = "Windows", Name = "Foo" }, new Device { OS = "Mac", Name = "Bar" } }; var filters = new List> { d => d.OS }; var result = FilterDevices(devices, filters, "Windows");
这只是一个粗略的想法 – 根据需要转换为您的解决方案!
你基本上有两个选择:
- 使用System.Linq.Expression API来构建LINQ谓词(如果做得好的话,可以使用很多可重用的解决方案)。 您仍然需要在某些内容上映射filter名称和属性(例如,相同的名称)
- 硬编码filter名称与
Func
谓词之间的映射。 您可以在静态字典(或普通旧字典)中执行此操作。 只需确保在谓词上创建闭包并绑定filter值。 Where调用期望Func
private IQueryable FilterCentraStageDeviceList(List centraStageDevices, string filter, string filterValue) { IQueryable alldevices = centraStageDevices.AsQueryable (); IQueryable query = new List ().AsQueryable(); if (filter == null || string.IsNullOrEmpty(filterValue)) { return alldevices; } filterValue = filterValue.ToLower(); var filterLower = filter.ToLower(); if (filterLower.Contains("all") || (filterLower.Contains("hostname") && filterLower.Contains("operatingsystem") && filterLower.Contains("status") && filterLower.Contains("lastloggedinuser"))) { return alldevices.Where(x => checkNull(x.Name).Contains(filterValue) || checkNull(x.OperatingSystem).Contains(filterValue) || checkNull(x.LastUser).Contains(filterValue)); } if (filterLower.Contains("hostname")) { query = alldevices.Where(x => checkNull(x.Name).Contains(filterValue)); } if (filterLower.Contains("operatingsystem")) { query = alldevices.Where(x => checkNull(x.OperatingSystem).Contains(filterValue)).Union(query); } if (filterLower.Contains("lastloggedinuser")) { query = alldevices.Where(x => checkNull(x.LastUser).Contains(filterValue)).Union(query); } return query; }
这是我最后使用的,因为我不允许使用外部dll,即使谓词构建器是我的场景的适当解决方案。
上述就是C#学习教程:使用Linq进行动态过滤分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。
如若转载,请注明出处:https://www.ctvol.com/cdevelopment/1016620.html