【问题标题】:EF 6 Code-First Many to Many relationship with same entity on non-primary keyEF 6 代码优先多对多关系与非主键上的同一实体
【发布时间】:2019-02-13 16:59:14
【问题描述】:

我有一个 EF 6 任务实体,如下所示:

public class Task
{
    public Guid TaskId {get; set;}
    public TaskTypeEnum TaskType {get; set;}
    public TaskStatusEnum TaskStatus {get; set;}

    public virtual ICollection<Task> Dependencies {get; set;}
}

某种类型的任务可以依赖于某种类型的所有其他任务在它们运行之前完成运行,并且这些依赖关系应该在这样的表中定义:

public class TaskTypeDependency
{
    public TaskTypeEnum TaskType {get; set;}
    public TaskTypeEnum DependsOnTaskType {get; set;}
}

我想要的示例-任务 A 的类型为 1,任务 B 和 C 的类型为 2。我的 TaskTypeDependency 为

TaskType | DependsOnTaskType
----------------------------
1        |  2              

在运行时,我想获取该任务所依赖的所有任务,对于任务 A 来说,任务 B 和任务 C 是为了检查相关任务是否已完成。有没有办法在 Code-First 中建立这种关系,也许使用 Fluent API?还是我在没有虚拟属性的情况下使用 LINQ 来解决所有问题?

【问题讨论】:

  • 那么类型1的所有任务都依赖于类型2的所有任务?如果是这样,您可以简单地检查类型 2 的所有任务是否已完成,如果您想知道是否可以完成类型 1 的 任何 任务。你不需要这个Dependencies 集合。

标签: c# .net database entity-framework entity-framework-6


【解决方案1】:

欢迎来到 StackOverflow!

据我所知,EF 无法处理此类关系。

您的问题不在于主键不是主键。您的主要问题是这些键 (TaskTypes) 不是唯一的

解决方案建议

您可以通过封装在存储库中加载相关任务的逻辑来解决此限制。虽然很多人 advice against 在 EF 之上构建存储库模式,而且大多数时候我也站在那一边,这是一个很好的例子,说明它为什么有用。

我将创建一个使用 LINQ 填充依赖项的方法,也许是一个扩展方法,类似于以下内容:

private static void LoadDependentTasks(this Task task, IEnumerable<Task> allTasks){
    task.Dependencies = allTasks.Where(yourCustomSelector).ToList();
}

然后在您的存储库中,您可以在返回之前对加载的任务使用此方法。例如:

public Task GetById(Guid taskId){
    Task t = _context.Tasks.Find(taskId);
    t.LoadDependentTasks(_context.Tasks);
}

然后,当您的业务逻辑调用您的存储库时,它将接收已经填充了 Dependencies 属性的对象。

不过,这里有一个值得一提的优化。它对于获得单个任务并不重要,但在加载所有任务时会产生很大的不同。如果你天真地实现 GetAll 方法,如下所示,它将从服务器检索任务列表 n,这不是很好。

public Task GetAll(){
    List<Task> allTasks = _context.Tasks.ToList();
    foreach(var task in allTasks)
        task.LoadDependentTasks(_context.Tasks);
    return allTasks;
}

您应该将已经存在的allTasks 变量传递给该方法。如果 - 在另一种情况下 - 您还没有任务列表,另一种解决方案是调用 _context.Tasks.Load(),然后使用 _context.Tasks.Load

【讨论】:

    猜你喜欢
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多