C# 我是否可以使用Func/谓词或Linq表达式创建列表的通用筛选<;T>;?

C# 我是否可以使用Func/谓词或Linq表达式创建列表的通用筛选<;T>;?,c#,.net,linq,C#,.net,Linq,使用以下类模型 public class Client { public string Name; public List<Projects> Projects; } public class Projects { public string Value; } 公共类客户端 { 公共字符串名称; 公开项目清单; } 公共类项目 { 公共字符串值; } 我想创建几个方法:GetHighGoldCustomers();GetHighSilverCustomers();GetHigh

使用以下类模型

public class Client
{
public string Name;
public List<Projects> Projects;
}

public class Projects
{
public string Value;
}
公共类客户端
{
公共字符串名称;
公开项目清单;
}
公共类项目
{
公共字符串值;
}
我想创建几个方法:
GetHighGoldCustomers();GetHighSilverCustomers();GetHighBronzeCustomers()
。。。。等

我们有大约15种不同的评级

客户的评级取决于项目的价值,因此对于GetHighGoldCustomers(),我希望获得所有客户以及价值>200的项目

进一步解释: 我想把列表拿回来。每个客户都有一个列表
,这些项目将是客户项目的子集

我可以通过创建一个通用方法来实现这一点吗?在该方法中,我将表达式作为一个参数传递,然后返回一个过滤掉的
列表和相关列表


谢谢

你是说这样的事吗

private List<Client> ClientsWithValueGreaterThan(int value)
{
    return Clients.Where(c => c.Projects.Sum(p => p.Value) > value)
}

是的,您可以将表达式作为参数传递..如下所示↓

    public static IEnumerable<T> GetResultByCondtion<T>(
        IQueryable<T> src, 
        Expression<Func<T, bool>> predicate)
    {
        return src.Where(predicate);
    }
公共静态IEnumerable GetResultByCondition(
易读src,
表达式(谓词)
{
返回src.Where(谓词);
}
用法:

        var result = GetResultByCondtion<Client>(Clients.AsQueryable() , 
            c=>c.Projects.Sum(p=>p.Value) > 20);

        Console.WriteLine(result.Count());
        Console.ReadKey();
var result=getresultbycondition(Clients.AsQueryable(),
c=>c.Projects.Sum(p=>p.Value)>20);
Console.WriteLine(result.Count());
Console.ReadKey();

我将考虑创建一组扩展方法来解决您的问题。大概是这样的:

public static class ClientEx
{
    public static List<Client> GetCustomersByProjects(
        this IEnumerable<Client> clients,
        Func<IEnumerable<Projects>, IEnumerable<Projects>> selector)
    {
        var query =
            from c in clients
            let ps = selector(c.Projects).ToList()
            where ps.Any()
            select new Client()
            {
                Name = c.Name,
                Projects = ps,
            };

        return query.ToList();
    }

    public static List<Client> GetCustomersByProjectValuesGreaterThan(
        this IEnumerable<Client> clients, int value)
    {
        return clients.GetCustomersByProjects(ps => ps.Where(p => p.Value > value));
    }

    public static List<Client> GetHighGoldCustomers(
        this IEnumerable<Client> clients)
    {
        return clients.GetCustomersByProjectValuesGreaterThan(200);
    }
}
然后,将以下代码添加到扩展类:

private static Dictionary<
        ClientRating, Func<IEnumerable<Projects>, IEnumerable<Projects>>>
    _ratingSelectors = new Dictionary<
        ClientRating, Func<IEnumerable<Projects>, IEnumerable<Projects>>>()
    {
        { ClientRating.HighGold, ps => ps.Where(p => p.Value > 200) },
        { ClientRating.HighSilver, ps => ps.Where(p => p.Value > 125) },
        { ClientRating.HighBronze, ps => ps.Where(p => p.Value > 60) },
        { ClientRating.Gold, ps => ps.Where(p => p.Value > 175) },
        { ClientRating.Silver, ps => ps.Where(p => p.Value > 100) },
        { ClientRating.Bronze, ps => ps.Where(p => p.Value > 40) },
        { ClientRating.LowGold, ps => ps.Where(p => p.Value > 150) },
        { ClientRating.LowSilver, ps => ps.Where(p => p.Value > 80) },
        { ClientRating.LowBronze, ps => ps.Where(p => p.Value > 20) },
    };

public static List<Client> GetCustomersByRating(
    this IEnumerable<Client> clients,
    ClientRating rating)
{
    return clients.GetCustomersByProjects(_ratingSelectors[rating]).ToList();
}
这段代码的好处在于,评级的定义都保存在代码中的一个位置,如果需要更改评级系统而无需重新编译,还可以在运行时修改字典

如果评级系统依赖于
客户机
上的属性,而不仅仅是项目列表,并且需要在返回
HighSilver
时过滤掉
HighGold
客户机,我怀疑您需要更改
选择器
表达式


这有帮助吗?

未筛选的客户端集是作为内存集合管理的,还是您使用的是ORM(如Entity Framework)?此外,如果一个客户端有两个项目,每个项目的值为100,这是否使他们成为黄金客户(总和为200),还是他们需要使用.net 4.0拥有一个值>200的项目。内存收集。我想分别返回值大于200的所有项目,然后我们使用历史数据获得每个项目的评级限制值,以决定评级。所以简而言之,我需要得到一个列表。列出那些大于输入值的项目。或者也可以查询项目类的任何其他属性(在实际项目中,客户机和项目类的属性、创建日期、修改日期等超过20个)。
var customers = new List<Client>();
// load customers       
var highGold = customers.GetHighGoldCustomers();
var moreThan100 = customers.GetCustomersByProjectValuesGreaterThan(100);
public enum ClientRating
{
    HighGold,
    HighSilver,
    HighBronze,
    Gold,
    Silver,
    Bronze,
    LowGold,
    LowSilver,
    LowBronze,
    // etc
}
private static Dictionary<
        ClientRating, Func<IEnumerable<Projects>, IEnumerable<Projects>>>
    _ratingSelectors = new Dictionary<
        ClientRating, Func<IEnumerable<Projects>, IEnumerable<Projects>>>()
    {
        { ClientRating.HighGold, ps => ps.Where(p => p.Value > 200) },
        { ClientRating.HighSilver, ps => ps.Where(p => p.Value > 125) },
        { ClientRating.HighBronze, ps => ps.Where(p => p.Value > 60) },
        { ClientRating.Gold, ps => ps.Where(p => p.Value > 175) },
        { ClientRating.Silver, ps => ps.Where(p => p.Value > 100) },
        { ClientRating.Bronze, ps => ps.Where(p => p.Value > 40) },
        { ClientRating.LowGold, ps => ps.Where(p => p.Value > 150) },
        { ClientRating.LowSilver, ps => ps.Where(p => p.Value > 80) },
        { ClientRating.LowBronze, ps => ps.Where(p => p.Value > 20) },
    };

public static List<Client> GetCustomersByRating(
    this IEnumerable<Client> clients,
    ClientRating rating)
{
    return clients.GetCustomersByProjects(_ratingSelectors[rating]).ToList();
}
var highGolds = customers.GetCustomersByRating(ClientRating.HighGold);
var silvers = customers.GetCustomersByRating(ClientRating.Silver);
var lowBronzes = customers.GetCustomersByRating(ClientRating.LowBronze);