【发布时间】:2014-03-12 10:02:23
【问题描述】:
我一直在研究一些 LINQ,但我似乎无法弄清楚如何过滤这些数据。我对 LINQ 还是很陌生,这是我遇到的第一个真正的绊脚石。
我有桌子:
任务ID |姓名 |类型ID |父任务ID
价值观:
1 |任务名称 | 1 |空
2 |任务名称| 6 |空
3 |任务名称| 6 | 4
4 |任务名称| 2 |空
5 |任务名称| 6 | 4
6 |任务名称| 3 | 4
7 |任务名称| 6 | 1
8 |任务名称| 6 | 1
9 |任务名称| 2 |空
子任务是具有 ParentTaskID 的任务。
我需要获得所有符合此条件的任务:
- 如果 Task 没有分配的 SubTasks 且 TypeID = 6,则删除 Task
- 如果 ParentTask 的 SubTasks ALL 的 TypeID = 6,则删除 Parent 和 Subtasks
因此我希望能回来
3 |任务名称| 6 | 4
4 |任务名称| 2 |空
5 |任务名称| 6 | 4
6 |任务名称| 3 | 4
9 |任务名称| 3 |空
上表结果如下:
TaskID 1 已删除,因为 TaskID 7 和 8 是 TypeID = 6 的 SubTasks
TaskID 2 被移除,因为它没有 SubTasks 并且 TypeID = 6
TaskID 7 和 8 已删除,因为它们是父任务 1 的 TypeID = 6 的子任务
甚至可以在 LINQ 中执行此操作,还是我必须在 foreach 循环中执行此操作?
我的解决方案
所以我最终使用 Foreach 以老式方式执行此操作,并让 Resharper 将它可以转换回 LINQ 的内容。
var parents = tasks.Where(task => task.SubTasks.Any());
var tasksWithNoSubs = tasks.Where(task => !task.SubTasks.Any());
var parentIdsToRemove = new List<int?>();
var childIdsToRemove = new List<int?>();
foreach (var parent in parents)
{
var children = tasks.Where(task => task.ParentTaskID == parent.Id);
if (children.All(task => task.StatusId == 6))
{
parentIdsToRemove.Add(parent.Id); //mark this parent for removal
childIdsToRemove.AddRange(Enumerable.Select(children.Select(child => child.Id), dummy => (int?) dummy));
}
}
//get all Tasks that have NO Subtasks and also have a StatusID = 6
parentIdsToRemove.AddRange(Enumerable.Select((from task in tasksWithNoSubs where task.StatusId == 6 select task.Id), dummy => (int?) dummy));
//get a list of children with an Id contained in the list parentIdsToRemove
var tasksToRemove =
tasks.Where(task => parentIdsToRemove.Contains(task.Id) || childIdsToRemove.Contains(task.Id));
//remove the tasks from the collection
tasks = tasks.Where(task => !tasksToRemove.Contains(task));
【问题讨论】:
-
不应该删除 2 和 3,因为 2 有一个类型为 6 的子任务吗? (而不是因为没有子任务而只删除了 2 个)?不应该删除 9,因为它没有 id 为 6 的子任务(实际上根本没有子任务)?等等,对于最后一个,第一个标准是否应该被声明为“删除 TypeID = 6 且没有子任务的任务”?我把它读作 typeid=6... 的子任务
-
为了实际解决这个问题,我想先加入一些组合,然后按父任务分组,然后为可以查看分组子任务的两个标准中的每一个添加一个 where 子句。我不确定我是否可以自己编写查询,但希望这会给您一个开始的想法。
-
嘿克里斯,很可能我有一些结果不正确,所以请原谅我。我现在更新了 OP,给 3 一个 4 的父母,希望这看起来是正确的。
-
9 不应该被移除,因为它没有 Sub Tasks 并且没有 TypeID = 6
-
您需要在实际问题中阐明您的第一个项目符号。是说“删除 TypeID 为 6 且没有子任务的任务”还是“删除没有 TypeID = 6 的子任务的任务”..? (注意,这就是为什么我们应该放弃自然语言而所有人都说 C++。Err,对不起,C# - 忘了我在哪里!)
标签: c# sql .net linq entity-framework