2014-02-05 62 views
0

我正在寻找使用Entity Framework 6构建“微软项目”式数据层次结构。基本上我需要的是可以跟踪不同级别的数据结构任务的细节。所以我期望构建一个支持类似以下内容的结构,其中任务可以具有子任务,子任务可以具有子任务等等,但是它不总是也不总是具有相同的深度。使用EF6构建“微软项目”式数据层次结构

Task 
-Task 
--Task 
--Task 
--Task 
---Task 
---Task 
--Task 

一些在这里的其他帖子提到,树的层次结构与实体框架非常困难,但我一直没能找到任何信息表明它是否自EF4改善,现在是那么困难。

我有一个但是任务模型如下一样,当我尝试生成它没有产生预期的数据库:我期待一个数据库,在那里我有一个任务表,以及儿童

public class Task 
{ 
    public int ID { get; set; } 

    public string Name { get; set; } 

    public virtual Task Parent { get; set; } 

    public virtual ICollection<Task> Children { get; set; } 
    public virtual ICollection<Task> Predecessors { get; set; } 
    public virtual ICollection<Task> Successors { get; set; } 
} 

,前辈和接班人表但是我结束了仅仅是一个任务表属性如下:

ID = c.Int(nullable: false, identity: true), 
Name = c.String(), 
Task_ID = c.Int(), 
Parent_ID = c.Int(), 
Task_ID1 = c.Int(), 
Task_ID2 = c.Int(), 

此外,我希望能够将多个不同的数据块与这些任务相关联。假设我的任务是“构建表”,并且我正在跟踪PersonA与PersonB构建它需要多长时间。将数据与该任务关联的最佳方式是什么?我应该使用TaskData对象类似如下:

public class TaskData 
{ 
    public int ID { get; set; } 

    public int CompletionTime { get; set; } 

    public virtual Task Task { get; set; } 
    public virtual Person Person { get; set; } 
} 

要的东西我也需要做出多个不同的任务相同的任务目标可重复使用的进一步复杂化。例如“Build Playground A”可能有子任务“Build a Table”的大小为1,而“Build Playground B”可能有子任务“Build a Table”的大小为2,但我只想让“Build a Table”任务在DB中存在一次然后通过TaskData对象关联数据。

提示或帮助确定如何解决上述任何问题将不胜感激。

回答

2

一旦你掌握了它,你的层次结构表并不是一个太难的概念。我一般工作数据库,先不要代码优先,所以我不能帮你的类定义以及其他,但理论如下....

你的任务应该是有以下栏目:

  • ID(这是(例如)主键)
  • 的ParentId(这是同一类型为ID的空列)
  • 你还需要什么

你应该再有一个relatio nship定义了表引用自身的位置,主键侧的Id和外键侧的ParentId。

你不应该有单独的表。所有任务将包含在一张表中。

然后你的TaskData应该定义自己的Id和其他你需要的东西。如果您希望TaskData在多个任务中可重复使用,请创建一个包含TaskDataId和TaskId列的多对多表,使用它们创建一个组合键并通过该表链接Tasks和TaskData。任何特定于任务和TaskData之间关系的数据都可以在链接表中定义。

如果您需要小心层次结构,请求大量数据时查询速度会变慢。每次循环往下,EF都会生成一个单独的查询。我强烈建议您检索完整的层次结构,实现使用公用表表达式(CTE)的存储过程并映射EF中的存储过程。

编辑 - 帮助任务类(请原谅我,如果不是完全正确,但它应该指向正确的方向)。

1 - 创建任务

public class Task 
{ 
[Key] 
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
public int TaskId { get; private set; } 
public string Name { get; set; } 
public int? ParentTaskId { get; private set; } 

[ForeignKey("ParentTaskId")] 
public Task ParentTask { get; set; } 

public List<Task> SubTasks { get; set; } 

public Task() 
{ 
SubTasks = new List<Task>(); 
} 
} 

2 - 一个DbSet自动属性添加到您的DbContext子

3 - 覆盖在你的DbContext类的OnModelCreated方法配置的关联。

public class YourContext : DbContext 
{ 
    public DbSet<Task> Tasks { get; set; } 

    // Other stuff 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Task>() 
      .HasMany(t => t.SubTasks) 
      .WithOptional(t => t.ParentTask); 
    } 
} 
+0

我同意应该只有一个任务表,我只是在想别人会跟踪任务如何相互关联。我唯一需要解释的就是如何跟踪id并获得EF来生成导航表。 – bbodenmiller

+0

@bbodenmiller原谅我,我不完全确定你的意思。当你说跟踪ID的时候,你指的是你提供的类中提到的“孩子”,“前辈”和“后继者”属性? –

+0

@bbodenmiller为了今晚帮助你的目的,我假设你的意思是我上面所说的。了解如何在步骤3中定义双向关联。 –