C# 基于Linq的动态滤波

C# 基于Linq的动态滤波,c#,linq,C#,Linq,我有一个列表。在设备类中有4个属性,即名称、操作系统、状态和最新日志用户。我需要写一个方法: IQueryable<Device> FilterDeviceList( List<Device> Devices, List<string> filter, string filterValue) 您基本上有两种选择: 使用System.Linq.Expression API构建您的Linq谓词(需要大量工作,但如果做得好,这是一个很好的可

我有一个
列表
。在
设备
类中有4个属性,即
名称
操作系统
状态
最新日志用户
。我需要写一个方法:

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

您基本上有两种选择:

  • 使用System.Linq.Expression API构建您的Linq谓词(需要大量工作,但如果做得好,这是一个很好的可重用解决方案)。您仍然需要将过滤器名称和属性映射到某个对象上(例如,相同的名称)
  • 硬编码筛选器名称与
    Func
    谓词之间的映射。您可以在静态字典(或普通的旧开关)中执行此操作。只需确保在谓词上创建闭包并绑定过滤器值。Where调用需要一个
    Func

  • 您基本上有两种选择:

  • 使用System.Linq.Expression API构建您的Linq谓词(需要大量工作,但如果做得好,这是一个很好的可重用解决方案)。您仍然需要将过滤器名称和属性映射到某个对象上(例如,相同的名称)
  • 硬编码筛选器名称与
    Func
    谓词之间的映射。您可以在静态字典(或普通的旧开关)中执行此操作。只需确保在谓词上创建闭包并绑定过滤器值。Where调用需要一个
    Func

  • 您可以按如下方式构建查询:

    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;
    }
    
    编辑、筛选名称属性:

    var r = FilterDeviceList(devices, new Device
                    {
                        Name = "yourFilterValue"
                    });
    
    编辑2,查看

    var predicate=PredicateBuilder.False();
    if(document.Name!=null)
    谓词=谓词。或(d=>d.Name==document.Name);
    如果(document.OS!=null)
    predicate=predicate.Or(d=>d.OS==document.OS);
    返回设备。其中(谓词);
    
    您可以按如下方式构建查询:

    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;
    }
    
    编辑、筛选名称属性:

    var r = FilterDeviceList(devices, new Device
                    {
                        Name = "yourFilterValue"
                    });
    
    编辑2,查看

    var predicate=PredicateBuilder.False();
    if(document.Name!=null)
    谓词=谓词。或(d=>d.Name==document.Name);
    如果(document.OS!=null)
    predicate=predicate.Or(d=>d.OS==document.OS);
    返回设备。其中(谓词);
    
    您可以这样做:

    public IEnumerable<Device> FilterDevices(IEnumerable<Device> devices, IEnumerable<Func<Device, string>> filters, string filterValue)
    {
        foreach (var filter in filters)
        {
            devices = devices.Where(d => filter(d).Equals(filterValue));
        }
    
        return devices;
    }
    
    用法:

    var devices = new List<Device>
    {
        new Device { OS = "Windows", Name = "Foo" },
        new Device { OS = "Mac", Name = "Bar" }
    };
    
    var filters = new List<Func<Device, string>>
    {
        d => d.OS
    };
    
    var result = FilterDevices(devices, filters, "Windows");
    
    var设备=新列表
    {
    新设备{OS=“Windows”,Name=“Foo”},
    新设备{OS=“Mac”,Name=“Bar”}
    };
    var filters=新列表
    {
    d=>d.OS
    };
    var结果=过滤器设备(设备、过滤器、“窗口”);
    

    这只是一个粗略的想法-根据需要转换您的解决方案

    您可以这样做:

    public IEnumerable<Device> FilterDevices(IEnumerable<Device> devices, IEnumerable<Func<Device, string>> filters, string filterValue)
    {
        foreach (var filter in filters)
        {
            devices = devices.Where(d => filter(d).Equals(filterValue));
        }
    
        return devices;
    }
    
    private IQueryable<Device> FilterCentraStageDeviceList(List<Device> centraStageDevices, string filter, string filterValue)
        {
            IQueryable<Device> alldevices = centraStageDevices.AsQueryable<Device>();
            IQueryable<Device> query = new List<Device>().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;
        }
    
    用法:

    var devices = new List<Device>
    {
        new Device { OS = "Windows", Name = "Foo" },
        new Device { OS = "Mac", Name = "Bar" }
    };
    
    var filters = new List<Func<Device, string>>
    {
        d => d.OS
    };
    
    var result = FilterDevices(devices, filters, "Windows");
    
    var设备=新列表
    {
    新设备{OS=“Windows”,Name=“Foo”},
    新设备{OS=“Mac”,Name=“Bar”}
    };
    var filters=新列表
    {
    d=>d.OS
    };
    var结果=过滤器设备(设备、过滤器、“窗口”);
    
    这只是一个粗略的想法-根据需要转换您的解决方案

    private IQueryable filter中央阶段设备列表(列出中央阶段设备、字符串过滤器、字符串过滤器值)
    
    private IQueryable<Device> FilterCentraStageDeviceList(List<Device> centraStageDevices, string filter, string filterValue)
        {
            IQueryable<Device> alldevices = centraStageDevices.AsQueryable<Device>();
            IQueryable<Device> query = new List<Device>().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;
        }
    
    { IQueryable alldevices=CentralStageDevices.AsQueryable(); IQueryable query=new List().AsQueryable(); if(filter==null | | string.IsNullOrEmpty(filterValue)) { 返回所有设备; } filterValue=filterValue.ToLower(); var filterLower=filter.ToLower(); if(filterLower.Contains(“全部”)|(filterLower.Contains(“主机名”)&&filterLower.Contains(“操作系统”)&&filterLower.Contains(“状态”)&&filterLower.Contains(“lastloggedinuser”)) { 返回所有设备。其中(x=>checkNull(x.Name)。包含(filterValue)| | checkNull(x.OperatingSystem)。包含(filterValue)| | checkNull(x.LastUser)。包含(filterValue)); } if(filterLower.Contains(“主机名”)) { query=alldevices.Where(x=>checkNull(x.Name).Contains(filterValue)); } if(filterLower.Contains(“操作系统”)) { query=alldevices.Where(x=>checkNull(x.OperatingSystem).Contains(filterValue)).Union(查询); } if(filterLower.Contains(“lastloggedinuser”)) { query=alldevices.Where(x=>checkNull(x.LastUser).Contains(filterValue)).Union(查询); } 返回查询; }
    这就是我最后使用的,因为我不允许使用外部dll,即使谓词生成器是适合我的场景的合适解决方案。

    private IQueryable filter centralstagedevicelist(列出centralstagedevices、string filter、string filterValue)
    {
    IQueryable alldevices=CentralStageDevices.AsQueryable();
    IQueryable query=new List().AsQueryable();
    if(filter==null | | string.IsNullOrEmpty(filterValue))
    {
    返回所有设备;
    }
    filterValue=filterValue.ToLower();
    var filterLower=filter.ToLower();
    if(filterLower.Contains(“全部”)|(filterLower.Contains(“主机名”)&&filterLower.Contains(“操作系统”)&&filterLower.Contains(“状态”)&&filterLower.Contains(“lastloggedinuser”))
    {
    返回所有设备。其中(x=>checkNull(x.Name)。包含(filterValue)| | checkNull(x.OperatingSystem)。包含(filterValue)| | checkNull(x.LastUser)。包含(filterValue));
    }
    if(filterLower.Contains(“主机名”))
    {
    query=alldevices.Where(x=>checkNull(x.Name).Contains(filterValue));
    }
    if(filterLower.Contains(“操作系统”))
    {
    query=alldevices.Where(x=>checkNull(x.OperatingSystem).Contains(filterValue)).Union(查询);
    }
    if(filterLower.Contains(“lastloggedinuser”))
    {
    query=alldevices.Where(x=>checkNull(x.LastUser).Contains(filterValue)).Union(查询);
    }            
    返回查询;
    }
    
    这就是我最后使用的,因为我不允许使用外部dll,即使谓词生成器是我的sce的合适解决方案