asp.net mvc EF代码中的多对多关系

时间:2013-01-23 16:56:55

标签: asp.net-mvc entity-framework ef-code-first code-first

我正在使用asp.net mvc 4,EF,codefirst与用户和角色系统建立多对多的关系

用户模型:

public class User
{
    #region properties

    [Key]
    public Int32 Id { get; set; }

    [Required]
    public String UserName { get; set; }

    public String Password { get; set; }

    [Required]
    public String Email { get; set; }

    public DateTime CreationDate { get; set; }

    public   DateTime LastUpdate { get; set; }

    public DateTime? LastLogin { get; set; }

    [ForeignKey("RoleId")]
    public virtual ICollection<Role> Roles { get; set; }

    #endregion //properties

    #region constructors

    public User()
    {
        Roles = new HashSet<Role>();

        LastUpdate = DateTime.Now;
        CreationDate = DateTime.Now;
    }

    #endregion //constuctors
}

角色模型:

public class Role
{
    [Key]
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public String Description { get; set; }
    public DateTime CreationDate { get; set; }
    public DateTime LastUpdate { get; set; }

    [ForeignKey("UserId")]
    public virtual ICollection<User> Users { get; set; }

    public Role() 
    {
        Users = new HashSet<User>();

        CreationDate = DateTime.Now;
        LastUpdate = DateTime.Now;
    }
}

上下文:

public class UserManagementContext : Context, IContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }

    public UserManagementContext() {
        Database.SetInitializer<UserManagementContext>(null);
    }

    void IContext.Setup(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().ToTable("Users");
        modelBuilder.Entity<Role>().ToTable("Roles");   
        modelBuilder.Entity<User>()
            .HasMany(u => u.Roles)
            .WithMany(r => r.Users)
            .Map(
                m =>
                {
                    m.MapLeftKey("UserId");
                    m.MapRightKey("RoleId");
                    m.ToTable("UserRoles");
                });
    }
}

生成数据库表时,表用户,角色和用户工具就在那里。然后我在用户中创建一个记录,一个在角色中,一个在userroles中进行连接。 userroles表有两列RoleId和UserId。

然后我尝试加载像这样的用户的角色:

public String[] GetRoles(String userName)
    {           
        //var user = ConcreteContext.Users.Include("Roles").Where(u => u.UserName == userName).FirstOrDefault();
        var users = ConcreteContext.Users.Include(u => u.Roles);
        var user = users.FirstOrDefault();

        var roles = from r in user.Roles
                    select r.Name;
        return roles.ToArray();
    }

var users = ConcreteContext.Users.Include(u => u.Roles);行会引发下一个错误:

System.Data.SqlClient.SqlException: Invalid object name 'dbo.RoleUsers'.

如果在创建de数据库时(通过使用m.ToTable(RoleUsers))将UserRoles的de table名称更改为RoleUsers,我会收到很多关于错误字段名称的错误。

有人知道我在这里缺少什么吗?

提前致谢,

威廉

2 个答案:

答案 0 :(得分:3)

您必须使用Fluent API的原因是什么?

您可以使用数据属性映射多对多:

public class User
{
    [InverseProperty( "Users" )]
    public virtual ICollection<Role> Roles {get;set;}
}

public class Role
{
    [InverseProperty( "Roles" )]
    public virtual ICollection<User> Users {get;set;}
}

答案 1 :(得分:0)

这将做我需要的事情:

public class User
{
    #region properties

    [Key]
    public Int32 Id { get; set; }

    [Required]
    public String UserName { get; set; }

    public String Password { get; set; }

    [Required]
    public String Email { get; set; }

    public DateTime CreationDate { get; set; }

    public   DateTime LastUpdate { get; set; }

    public DateTime? LastLogin { get; set; }

    [InverseProperty("Users")]
    public virtual ICollection<Role> Roles { get; set; }

    #endregion //properties

    #region constructors

    public User()
    {
        LastUpdate = DateTime.Now;
        CreationDate = DateTime.Now;
    }

    #endregion //constuctors
}

    public class Role
{
    [Key]
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public String Description { get; set; }
    public DateTime CreationDate { get; set; }
    public DateTime LastUpdate { get; set; }

    [InverseProperty("Roles")]
    public virtual ICollection<User> Users { get; set; }

    public Role() 
    {
        CreationDate = DateTime.Now;
        LastUpdate = DateTime.Now;
    }
}

public class UserManagementContext : Context, IContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }

    public UserManagementContext() {
        Database.SetInitializer<UserManagementContext>(null);
    }

    void IContext.Setup(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().ToTable("Users");
        modelBuilder.Entity<Role>().ToTable("Roles");               
    }
}