我真的处于一个我想不出关于linq中可选分组的答案的位置。
基本上,我想生成来自具有过滤器的屏幕的报告。这些过滤器(大部分是分组的)是可选的,可以重新排列。它有点像
Filters: 1.Clients Projects Tasks Duration
or
2.Projects Clients Tasks Duration
or
3.Task Duration etc.
与所有可能的组合。那么数据应该看起来像
1.ClientA
ProjectA
TaskA
26hrs 45mins
TaskB
43hrs 23mins
ProjectB
TaskX......
2.ProjectA
ClientA
TaskA
26hrs 45mins...
3.TaskA
26hrs 45mins
TaskB
6hrs 35mins
我有数据。但无法编写通用的逻辑。
我正在考虑一些枚举,它将容纳过滤器(视图模型)选择,例如 枚举。客户端,枚举。项目。。。和
if (clientGroupChecked) then
foreach(var clientGroup in list){
//group list by client here
if(projectGroupChecked) then
foreach(var projectGroup in clientGroup){
//group list by project here
}
}
我知道,这是错误的。这样,我必须为所有可能的组合输入逻辑。
想不出别的了。我希望它真的是通用的,因为它将来可能会添加更多过滤器,并且我不想仅仅为了额外的过滤器而更改整个逻辑(当然,我想在逻辑中的某个地方添加新的过滤器组。但我希望它也更容易维护。
编辑:
@sschimmel :我的观点是分组可以洗牌(为此我有按钮[选中 -->绿色和未选择-->灰色,这些按钮可以移动以进行分组]。
那么在编写linq逻辑时,我怎么知道我必须以特定方式分组的条件呢?
例如:我有列 A B C D E F.In,我可以选择按 A 或 A B 或 B A 或 ACB 分组......等等。与所有可能的组合。如何实现这一点?我不想检查,因为我们有很多可能性。如果再添加一个过滤器,它将有更多的可能性。这就是为什么我认为需要通用方法来做到这一点。
编辑 2:
请在下面找到附件以及我如何尝试。
//for the following ,I need some way of writing properly passing right values
var reportGroupingCP = (from t in TaskEntries
group t by new { clientId,projectId } into g
select new
{
ClientId = g.Key.clientId,
ProjectId = g.Key.projectId,
Result = (Type)g //What could be T
}).ToList();
var reportGroupingCE = (from t in TaskEntries
group t by new { clientId,employeeId } into g
select new
{
ClientId = g.Key.clientId,
EmployeeId = g.Key.employeeId,
Result = (Type)g //What could be T
}).ToList();
//Can't use above if there is filter only for client.similarly for other cases/I don't want to write for each one.I need way to do this dynamically.May be by passing enum or adding ids to some class or something else
筛选器 1
筛选器 2
如果我正确理解了您的问题,您不想在多个属性上动态地对数据进行分组。
最简单的解决方案是使用动态 LINQ,它允许您从字符串创建查询,您可以轻松地从用户输入撰写。
// userSelections is created dynamically from what the user selected.
var userSelections = new[] { "clientId", "projectId" };
var propertiesToGroupBy = string.Join(", ", userSelections);
var groupedData = data.GroupBy("new(" + propertiesToGroupBy + ")");
它不是类型安全的,也不是在编译时检查的,但相当易于使用并解决了您的问题。它也记录得很好。
我试图想出一个动态组合Expression<Func<TaskEntry, object>>
的解决方案,但卡在创建Expression
来选择您将在GroupBy(new { ... })
中使用的匿名类型。由于在编译时不知道要作为分组依据的选定属性的数量,因此无法创建匿名类型。