实体框架中的聚合函数和自引用表

时间:2015-05-13 07:24:39

标签: c# entity-framework linq

我很难弄清楚如何在Entity Framework中处理自引用实体和聚合函数。我的表看起来像这样

Task
Id    ParentId    PercentageInParent    CompletedPercentage
0     null        null                  null
1     0           60                    null
2     0           40                    null
3     1           80                    40
4     1           20                    60
5     2           50                    80
6     2           50                    90

PercentageInParent是父子对这个子任务形式的百分比。我想看看一个任务,并通过总结其子元素来了解它的完成百分比。

编辑 具有子任务的任务(例如,任务1)将具有CompletedPercentage = null如果我想知道其CompletedPercentage我想要向下看树并计算子任务的完成方式。在这种情况下,任务1的完成率为44%,完成任务3和4的完成程度以及任务1下的权重。如何在EF中查询?

1 个答案:

答案 0 :(得分:1)

你应该添加另一个完成所有映射的类......

public class TaskMap
{
    public string TaskId { get; set; }
    public string TaskParentId { get; set; }
    public virtual Task Task { get; set; }
    public virtual Task ParentTask { get; set; }
}

public class Task
{
    public string TaskId { get; set; }
    public int Progress { get; set; }
    public virtual ICollection<TaskMap> SubTasks { get; set; }
}   

当您使用Entity Framework时,您需要更仔细地考虑数据库的设计方式......请记住它是relational数据存储,因此请通过规范化表单仍然很重要。

使用当前设计,您将始终拥有ParentId列为null的多条记录。这意味着您的设计中有一个重复元素需要提取并放在一个单独的表中。

新表TaskMaps应该包含一个复合主键,即TaskId和ParentTaskId。这将创建您的关系,然后您可以通过实现这样的方式来引用孩子。

var task = this.Context.Tasks.FirstOrDefault(tasks => tasks.TaskId == "random guid")
task.SubTasks.SelectMany(tasks => tasks.SubTasks)
             .Select(sub => sub.Task);