使用以下课堂模型
public class Client
{
public string Name;
public List<Projects> Projects;
}
public class Projects
{
public string Value;
}
我想创建一些方法:GetHighGoldCustomers(); GetHighSilverCustomers(); GetHighBronzeCustomers()
....等
我们有大约15种不同的评级。
客户的评级取决于项目的价值,因此对于GetHighGoldCustomers(),我希望得到所有客户和那些有价值&gt;的项目。 200
进一步解释:
我想要List&lt; Client>
。每个客户端都有List <Project>
,这些项目将成为客户项目的子集。
我是否可以通过创建一个通用方法来实现这一点,在该方法中我将Expression作为参数传递,然后返回过滤掉的List<Client> and related List<Project>
?
谢谢
答案 0 :(得分:1)
是的,您可以将表达式作为参数传递..就像这个↓
public static IEnumerable<T> GetResultByCondtion<T>(
IQueryable<T> src,
Expression<Func<T, bool>> predicate)
{
return src.Where(predicate);
}
用法:
var result = GetResultByCondtion<Client>(Clients.AsQueryable() ,
c=>c.Projects.Sum(p=>p.Value) > 20);
Console.WriteLine(result.Count());
Console.ReadKey();
答案 1 :(得分:0)
你的意思是这样的吗?
private List<Client> ClientsWithValueGreaterThan(int value)
{
return Clients.Where(c => c.Projects.Sum(p => p.Value) > value)
}
然后,基于此,您可以创建您描述的方法:
public GetHighGoldCustomers()
{
return ClientsWithValueGreaterThan(200);
}
public GetHighSilverCustomers()
{
return ClientsWithValueGreaterThan(100);
}
答案 2 :(得分:0)
我会考虑创建一组扩展方法来解决您的问题。像这样:
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);
}
}
然后你可以在任何IEnumerable<Client>
上使用这些方法,如下所示:
var customers = new List<Client>();
// load customers
var highGold = customers.GetHighGoldCustomers();
var moreThan100 = customers.GetCustomersByProjectValuesGreaterThan(100);
现在,如果我能够坚持下去,我建议您创建一种方法,通过您在问题中提到的15个评级中的任何一个来回报客户。
首先,创建一个枚举来表示评级:
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);
这段代码的好处在于,评级的定义都保存在代码中的一个位置,如果您需要在不重新编译的情况下更改评级系统,也可以在运行时对字典进行修改。 / p>
如果评级系统依赖于selector
上的属性而不仅仅是项目列表,并且如果您需要,例如,过滤器,我怀疑您需要更改Client
表达式返回HighGold
时退出HighSilver
个客户。
这有帮助吗?