C# 使用EF Core 5的Direct和Indirec多对多配置使用

C# 使用EF Core 5的Direct和Indirec多对多配置使用,c#,.net,entity-framework-core,ef-core-5.0,C#,.net,Entity Framework Core,Ef Core 5.0,我有以下实体 public class Course { public long Id { get; set; } public virtual ICollection<User> Users{ get; set; } public virtual ICollection<UserCourse> CourseUsers { get; set; } } public class User { public long Id { get; se

我有以下实体

public class Course
{
    public long Id { get; set; }
    public virtual ICollection<User> Users{ get; set; }
    public virtual ICollection<UserCourse> CourseUsers { get; set; }
}

public class User
{
    public long Id { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
    public virtual ICollection<UserCourse> UserCourses { get; set; }
}

public class UserCourse
{
    public long UserId { get; set; }
    public User User { get; set; }

    public long CourseId { get; set; }
    public Course Course { get; set; }

    public bool IsRequired { get; set; }
}
以及用户映射

        builder
            .HasMany(nav => nav.Courses)
            .WithMany(nav => nav.Users);
当尝试创建一个新的迁移时,我不太清楚为什么我会得到这个

无法对实体类型“UserCourse”使用表“UserCourse”,因为它是 用于实体类型“UserCourse(Dictionary)”的 和其他可能的实体类型,但没有链接 关系将外键添加到主键上的“UserCourse” 属性,并指向另一个键入的实体上的主键 映射到“UserCourse”

我理解错误是什么,但不确定如何强制UserCourse映射使用用户映射生成的联接表,或者反之亦然


另外,我还需要OData的direcat映射,以及使用join实体对
DbSet

课程
实体中的
公共虚拟ICollection用户{get;set;}
公共虚拟ICollection课程{get;set;}执行操作的间接映射
中的
用户
实体是冗余的。实体应该更像这样

public class Course
{
   public long Id { get; set; }
   public virtual ICollection<UserCourse> UserCourses { get; set; }
}

public class User
{
   public long Id { get; set; }
   public virtual ICollection<UserCourse> UserCourses { get; set; }
}

public class UserCourse
{
    public long UserId { get; set; }
    public User User { get; set; }

    public long CourseId { get; set; }
    public Course Course { get; set; }

}
公共课
{
公共长Id{get;set;}
公共虚拟ICollection用户课程{get;set;}
}
公共类用户
{
公共长Id{get;set;}
公共虚拟ICollection用户课程{get;set;}
}
公共课程
{
公共长用户标识{get;set;}
公共用户{get;set;}
公共长线ID{get;set;}
公共课程{get;set;}
}
OnModelCreating方法应该有以下代码

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<UserCourse>()
               .HasKey(uc => new { uc.UserId, uc.CourseId }); 

   modelBuilder.Entity<UserCourse>()
               .HasOne(uc => uc.Course)
               .WithMany(c => c.Users)
               .HasForeignKey(uc => uc.CourseId); 

   modelBuilder.Entity<UserCourse>()
               .HasOne(uc => uc.User)
               .WithMany(c => c.Courses)
               .HasForeignKey(uc => uc.UserId);  

    }
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasKey(uc=>new{uc.UserId,uc.CourseId});
modelBuilder.Entity()
.HasOne(加州大学=>加州大学课程)
.WithMany(c=>c.Users)
.HasForeignKey(uc=>uc.CourseId);
modelBuilder.Entity()
.HasOne(uc=>uc.User)
.有许多(c=>c.课程)
.HasForeignKey(uc=>uc.UserId);
}

如果使用EF core 5,则可以直接跳过联接表。它将由EF在幕后生成和处理。这里有更多关于这个话题的内容

就像我说的,我想保留这两个链接。我不确定这是否可行。既然您可以从
UserCourse
访问
UserCourse
用户,为什么要同时保留
public virtual ICollection用户{get;set;}
public virtual ICollection课程用户{get;set;}
?我不知道该怎么利用这个。问题的关键是保留两个导航道具,并将joinTable作为DbSet公开。好吧,文档的这一部分正好涵盖了您的情况,不是吗?请参阅“创建定制CLR类型”
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   modelBuilder.Entity<UserCourse>()
               .HasKey(uc => new { uc.UserId, uc.CourseId }); 

   modelBuilder.Entity<UserCourse>()
               .HasOne(uc => uc.Course)
               .WithMany(c => c.Users)
               .HasForeignKey(uc => uc.CourseId); 

   modelBuilder.Entity<UserCourse>()
               .HasOne(uc => uc.User)
               .WithMany(c => c.Courses)
               .HasForeignKey(uc => uc.UserId);  

    }