C# 如何公开联接表?

C# 如何公开联接表?,c#,entity-framework,ef-code-first,ef-fluent-api,C#,Entity Framework,Ef Code First,Ef Fluent Api,我试图从一开始就遵循这个想法,避免在ORMs中使用多对多映射 鉴于此设置,我希望能够直接公开关系中的“Join”对象 物体 使用者 角色 用户角色(关联对象) 代码: public class User { public Guid Id { get; set; } public string Name { get; set; } public virtual ICollection<Role> Roles { get; set; } } public c

我试图从一开始就遵循这个想法,避免在ORMs中使用多对多映射

鉴于此设置,我希望能够直接公开关系中的“Join”对象

物体

  • 使用者
  • 角色
  • 用户角色(关联对象)
代码:

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
}

public class Role
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<User> Users { get; set; }
}

public class UserRole
{
    public Guid UserId { get; set; }
    public Guid RoleId { get; set; }
    public User User { get; set; }
    public Role Role { get; set; }
}

public class MyContext : DbContext 
{

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //modelBuilder.Entity<UserRole>().HasKey(u => new { u.RoleId, u.UserId });
        modelBuilder.Entity<User>().HasMany(x => x.Roles).WithMany(x => x.Users).Map(m =>
        {
            m.ToTable("UserRoles");
            m.MapLeftKey("UserId");
            m.MapRightKey("RoleId");
        });
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    //public DbSet<UserRole> UserRoles { get; set; } 
}
只要我向UserRoles对象的DbContext添加一个DBset。EF找不到UserRoles对象的PK

UserRoles:EntityType:EntitySet“UserRoles”基于未定义密钥的类型“UserRole”

然后,我尝试按如下方式指定密钥:

modelBuilder.Entity<UserRole>().HasKey(u => new { u.RoleId, u.UserId });
如何指示DbModelBuilder只使用单个UserRole表


我在

上有一个关于这个问题的演示.sln,我想你把两件事混在一起了

如果要公开
M:N
表,则不能在实体框架中使用
M:N
关联,因为实体框架会为您隐藏该关联。然后应该将其映射为两个
1:M
N:1
关联。在这种情况下,您将强制实体框架以这种方式考虑它,而不是以
M:N
的方式考虑它。当您自己在这个关联中进行查询时,您必须指定所有条件(这可能是您想要做的)。基本上是代表您加入实体框架


但你也可以同时使用两个世界。尽管这可能很危险,但您必须小心地进行更新、删除等操作。您可以创建一个视图,即
MyUserRoles
,它只是
select*from UserRoles
并将其映射为
UserRoles
实体的支持“表”。但正如我所说的,在更改时应该非常小心,因为更改
MyUserRoles
很容易混淆
DbContext
,而实体框架认为
M:N

中没有更改,这并不能避免多对多,这只是单向的多对多。是的,我再次阅读了这篇文章,现在看到你必须放弃多对多来公开连接表。
modelBuilder.Entity<UserRole>().HasKey(u => new { u.RoleId, u.UserId });
CreateTable(
"dbo.UserRoles1",
c => new
    {
        RoleId = c.Guid(nullable: false),
        UserId = c.Guid(nullable: false),
    })
.PrimaryKey(t => new { t.RoleId, t.UserId })
.ForeignKey("dbo.Roles", t => t.RoleId, cascadeDelete: true)
.ForeignKey("dbo.Users", t => t.UserId, cascadeDelete: true)
.Index(t => t.RoleId)
.Index(t => t.UserId);