[英]Direct and Indirec many-to-many configuration using EF Core 5 using
I have the following entities我有以下实体
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; }
}
with the following mappings for具有以下映射
UserCourse mapping:用户课程映射:
builder
.HasOne(nav => nav.User)
.WithMany(self => self.UserCourses)
.HasForeignKey(fk => fk.UserId)
.OnDelete(DeleteBehavior.Cascade);
builder
.HasOne(nav => nav.Course)
.WithMany(self => self.CourseUsers)
.HasForeignKey(fk => fk.CourseId)
.OnDelete(DeleteBehavior.Cascade);
and the User mapping和用户映射
builder
.HasMany(nav => nav.Courses)
.WithMany(nav => nav.Users);
When trying to create a new migration I'm not exactly sure why I'm getting this.当尝试创建一个新的迁移时,我不确定我为什么会得到这个。
Cannot use table 'UserCourse' for entity type 'UserCourse' since it is being used for entity type 'UserCourse(Dictionary<string, object>)' and potentially other entity types, but there is no linking relationship.不能将表 'UserCourse' 用于实体类型 'UserCourse',因为它正在用于实体类型 'UserCourse(Dictionary<string, object>)' 和可能的其他实体类型,但没有链接关系。 Add a foreign key to 'UserCourse' on the primary key properties and pointing to the primary key on another entity typed mapped to 'UserCourse'.将外键添加到主键属性上的“UserCourse”,并指向映射到“UserCourse”的另一个实体上的主键。
I understand what the error is, but not sure how to force the UserCourse mapping to use the User mapping generated join table or vice-versa我了解错误是什么,但不确定如何强制 UserCourse 映射使用用户映射生成的连接表,反之亦然
Also, I need the direcat mapping for OData, and the indirect mapping using the join entity to conduct operations on DbSet<UserCourse>
另外,我需要 OData 的直接映射,以及使用连接实体的间接映射来对DbSet<UserCourse>
进行操作
The public virtual ICollection<User> Users{ get; set; }
public virtual ICollection<User> Users{ get; set; }
public virtual ICollection<User> Users{ get; set; }
public virtual ICollection<User> Users{ get; set; }
in Course
entity and the the public virtual ICollection<Course> Courses { get; set; }
public virtual ICollection<User> Users{ get; set; }
在Course
实体和public virtual ICollection<Course> Courses { get; set; }
public virtual ICollection<Course> Courses { get; set; }
public virtual ICollection<Course> Courses { get; set; }
in Users
entity are redundant. Users
实体中的public virtual ICollection<Course> Courses { get; set; }
是多余的。 The entities should look more like this实体应该看起来更像这样
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; }
}
And the OnModelCreating method should have this code并且 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);
}
If you use EF core 5 you can directly skip the join table.如果您使用 EF core 5,您可以直接跳过连接表。 It will be generated and handled by EF behind the scenes.它将由 EF 在幕后生成和处理。 More on the topic here https://www.thereformedprogrammer.net/updating-many-to-many-relationships-in-ef-core-5-and-above/更多关于这里的主题https://www.thereformedprogrammer.net/updating-many-to-many-relationships-in-ef-core-5-and-above/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.