【问题标题】:c# & EF: How to make a many to many relationship to an entity itself?c# & EF:如何与实体本身建立多对多关系?
【发布时间】:2021-07-18 16:32:13
【问题描述】:

我有一个任务实体,每个任务都可以有前面和后面的任务,或者没有。所以我的任务应该和它本身有多对多的关系。而且我在这两个任务之间做了一个联结表TaskAssignment,但是在编译EF的时候报错:无法确定ICollection类型的navigation'AppTask.TaskAssignments'所代表的关系。我想我需要将 PrecedingTaskId 和 FollowTaskId 的外键显式声明为 AppTaskId,我尝试过但没有成功。请问我该如何解决?

public class AppTask
{
    public int Id { get; set; }
    public ICollection<TaskAssignment> TaskAssignments { get; set; }
}

public class TaskAssignment
{
    public int PrecedingTaskId { get; set; }
    public int FollowingTaskId { get; set; }
    public AppTask PrecedingTask { get; set; }
    public AppTask FollowingTask { get; set; }
}

【问题讨论】:

  • 我认为你不需要前置和跟随;你可以从中推断出一个。即使您从多个并行任务开始,我也会选择具有前面任务的任务。如果您需要从一开始就启动多个,请为例如 5 个后续同时执行的任务创建一个虚拟非任务以供参考

标签: c# entity-framework


【解决方案1】:

我认为自我参考对于您的场景来说已经足够了。我的意思是,您可以拥有引用同一张表的 ParentTaskId 的外键就足够了。这样,您将获得两个导航属性,一个用于 ParentTask,另一个用于子任务。

public class AppTask
   {
       public int Id { get; set; }
       public int? ParentTaskId { get; set; }

       public AppTask ParentTask { get; set; }
       public ICollection<AppTask> FollowingTasks { get; set; }
   }

【讨论】:

  • 我的“父”任务也应该是多个,自引用是否仍然适用于这个场景?
【解决方案2】:

我解决了。首先我添加了其他导航属性:

public class AppTask
{
    public int Id {get;set}
    public ICollection<TaskAssignment> PrecedingTaskAssignment{get;set}
    public ICollection<TaskAssignment> FollowingTaskAssignment{get;set}
}

我使用流利的 Api 进行配置:

        modelBuilder.Entity<TaskAssignment>().HasKey(c => new { c.PrecedingTaskId, c.FollowingTaskId });

        modelBuilder.Entity<TaskAssignment>()
            .HasOne(ta => ta.PrecedingTask)
            .WithMany(t => t.PrecedingTaskAssignments)
            .HasForeignKey(ta => ta.PrecedingTaskId)
            .OnDelete(DeleteBehavior.Restrict);

        modelBuilder.Entity<TaskAssignment>()
            .HasOne(ta => ta.FollowingTask)
            .WithMany(t => t.FollowingTaskAssignments)
            .HasForeignKey(ta => ta.FollowingTaskId)
            .OnDelete(DeleteBehavior.Restrict);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-08
    • 2015-06-09
    • 2016-06-19
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-12
    相关资源
    最近更新 更多