简体   繁体   English

实体框架中有多少关系正在发挥作用

[英]How many to many relationship in Entity Framework is working

I am using C# and Entity framework for building an authorization application. 我正在使用C#和Entity框架来构建授权应用程序。 I have user, Role, permission, claim table. 我有用户,角色,权限,索赔表。 As user and Role has many to many relationship, I have created the use-Role table. 由于用户和角色具有多对多关系,因此我创建了use-Role表。 I have problem with mapping relationship. 我有映射关系的问题。

This is my User class: 这是我的用户类:

 public class User
     {

    public int UserId { get; set; }

    public string UserName { get; set; }
}

This is my Role class: 这是我的角色类:

public class Role
{
    public int RoleId { get; set; }

    public string RoleName { get; set; }
}

I am not sure what I should have in User-Role class to make the many-to- many relationship work correctly specially when I am doing update. 我不确定在User-Role类中我应该具备什么才能使我在进行更新时特别正确地使用多对多关系。
This is my User-Role class: 这是我的用户角色类:

 public class UserRole
    {

    public UserRole()
    {
        Roles = new Collection<Role>();
        Users = new Collection<User>();
    }

    public int Id { get; set; }

    public int UserId { get; set; }

    public string UserName { get; set; }

    public int RoleId { get; set; }

    public string RoleName { get; set; }

}

and how the mapping should look like? 以及映射应该如何?

First beofre giving you the solution, just know that you are reinventing the wheel. 首先,为您提供解决方案,只要知道您正在重新发明轮子。 I said that because ASP.Net Identity just make what you are attempting to do. 我说过,因为ASP.Net Identity只是做你想做的事情。

Anyway some clarifications: 无论如何一些澄清:

  • UserRole is a association entity between User and Role UserRoleUserRole之间的关联实体
  • UserRole has required Role UserRole需要Role
  • UserRole has required User UserRole需要User

UserRole mean a combinaison between one User and one Role . UserRole表示一个User和一个Role You can have many instances of this as mutch as a User has many Role . 您可以将此实例作为mutch,因为User具有许多Role This is why before translating it with Fluent API you must remove Roles and Users collections that you put into UserRole and create instead UserRoles as an collection ICollection<UserRole> into User and Role. 这就是为什么用流利的API翻译它,你必须删除之前RolesUsers ,你投入的集合UserRole创造,而不是UserRoles作为一个集合ICollection<UserRole>到用户和角色。

Your classes must follow this: 你的课必须遵循这个:

User class: 用户类:

public class User
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<UserRole> UserRoles { get; set; }

    public User()
    {
        this.UserRoles = new Collection<UserRole>();
    }
}

Role class: 角色类:

public class Role
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<UserRole> UserRoles { get; set; }

    public Role()
    {
        this.UserRoles = new Collection<UserRole>();
    }
}

UserRole class: UserRole类:

public class UserRole
{
    public int Id { get; set; }

    public int UserId { get; set; }

    public User User { get; set; }

    public int RoleId { get; set; }

    public Role Role { get; set; }
}

No configuration needed, EF will use default convention and create all tables needed for you. 无需配置,EF将使用默认约定并创建所需的所有表。

In common when your join entity UserRole has no data property, I mean just foreign key, then you can remove it and just let User and Role as follow: 通常当您的连接实体UserRole没有数据属性时,我的意思是外键,然后您可以将其删除,只需让UserRole如下:

User class: 用户类:

public class User
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<Role> Roles { get; set; }

    public User()
    {
        this.Roles = new Collection<Role>();
    }
}

Role class: 角色类:

public class Role
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<User> Users { get; set; }

    public Role()
    {
        this.Users = new Collection<User>();
    }
}

Again no configuration needed, EF will create the tables and join table for you by using default conventions. 同样不需要配置,EF将使用默认约定为您创建表和连接表。

To learn a lot of things about EF, I recommend this web site Entity Framework Tutorials and if you can just read the following two books : 要了解有关EF的很多内容,我推荐这个网站Entity Framework Tutorials ,如果你能阅读以下两本书:

  • Programming Entity Framework: DbContext 编程实体框架:DbContext

  • Programming Entity Framework: Code First 编程实体框架:代码优先

If you just add the collection navigation properties to the User and Role entities, EF is going to create a many to many relationship by convention. 如果您只是将集合导航属性添加到UserRole实体,则EF将按惯例创建多对多关系。 In this case EF handles the junction table ( UserRoles ) for you, so, you don't need to map it if you don't need it. 在这种情况下,EF会为您处理联结表( UserRoles ),因此,如果您不需要它,则无需映射它。 In summary, your model could be this way: 总之,您的模型可能是这样的:

public class User
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual ICollection<Role> Roles { get; set; }
}

public class Role
{
    public int Id { get; set; }

    public string Name { get; set; }

   public virtual ICollection<User> Users { get; set; }
}

If you need ,for example, change the junction table's name or they PK's names, you can override OnModelCreating method in your context class and add this Fluent Api configuration: 例如,如果需要更改联结表的名称或PK的名称,可以在上下文类中重写OnModelCreating方法并添加此Fluent Api配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{

    modelBuilder.Entity<User>()
                .HasMany(s => s.Roles)
                .WithMany(c => c.Users)
                .Map(cs =>
                        {
                            cs.MapLeftKey("UserRefId");
                            cs.MapRightKey("RoleRefId");
                            cs.ToTable("UserRoles");
                        });

} 

And if you are using a mapping class, add the following configuration in the constructor of your UserMap class: 如果您使用的是映射类,请在UserMap类的构造函数中添加以下配置:

public UserMap()
{

    HasMany(s => s.Roles)
   .WithMany(c => c.Users)
   .Map(cs =>
              {
                 cs.MapLeftKey("UserRefId");
                 cs.MapRightKey("RoleRefId");
                 cs.ToTable("UserRoles");
              });
}

Agree with @octaviocci if you do not require a custom join table between Users and Roles. 如果您不需要用户和角色之间的自定义连接表,请同意@octaviocci。

However you seem to have a few custom properties in your UserRoles table, like "String Role" so maybe you want to have that join table have some custom fields in it. 但是,您似乎在UserRoles表中有一些自定义属性,如“String Role”,因此您可能希望该连接表中包含一些自定义字段。 If that is the case, then try this in your mapping for UserRoles 如果是这种情况,请在UserRoles的映射中尝试此操作

this.HasRequired(t => t.Roles).WithMany().HasForeignKey(fk => fk.RoleId); this.HasRequired(t => t.Roles)。WithMany()。HasForeignKey(fk => fk.RoleId); this.HasRequired(t => t.Users).WithMany().HasForeignKey(fk => fk.UserId); this.HasRequired(t => t.Users)。WithMany()。HasForeignKey(fk => fk.UserId);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM