Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping Join Tables In The Entity Framework

I am trying connect the asp.net membership tables in to an asp.mvc 3 website. I have been following the tutorial in Steve Sanderson's book 'Pro ASP.NET MVC 3 Framework' for the sport store and applying this to the tables that are generated from the membership exe.

So I have a user class that looks like:

namespace Domain.Entities
{
    public class User
    {
        public Guid UserId { get; set; }
        public string UserName { get; set; }
        public DateTime LastActivityDate;
        public virtual ICollection<Role> Roles { get; set; }
    }

    public class Role
    {
        public Guid RoleId { get; set; }
        public string RoleName { get; set; }
    }
}

and a context class that looks like:

public class EFDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().ToTable("aspnet_users");
        modelBuilder.Entity<Role>().ToTable("aspnet_roles");
    }
}

but I get an error because I assume it's looking for a join between these two tables when in fact there is a join table (aspnet_UsersInRoles) in between to avoid a many to many link, when I try and reference the Role model from the User, such as:

var test = _repository.Users.FirstOrDefault().Roles.Count();

{"Invalid column name 'User_UserId'.\r\nInvalid column name 'User_UserId'.\r\nInvalid column name 'User_UserId'."}

is there a way to map the table together using the join table using the entity framework? Is it better just to add a new ADO.NET entity data model and let visual studio just reverse engineer the database?

like image 243
GrahamJRoy Avatar asked Jan 16 '12 14:01

GrahamJRoy


1 Answers

You need to customize the many to many mapping as follows

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
       modelBuilder.Entity<User>().ToTable("aspnet_users");
       modelBuilder.Entity<Role>().ToTable("aspnet_roles");

       modelBuilder.Entity<User>()
       .HasMany(u => u.Roles).WithMany(r => r.Users)
            .Map(m =>
            {
                m.ToTable("aspnet_UsersInRoles");
                m.MapLeftKey("UserId");
                m.MapRightKey("RoleId");
            });
   }

Edit: You would also need to add Users property to the Role class. Otherwise the mapping should be changed to

       modelBuilder.Entity<User>()
       .HasMany(u => u.Roles).WithMany()
            .Map(m =>
            {
                m.ToTable("aspnet_UsersInRoles");
                m.MapLeftKey("UserId");
                m.MapRightKey("RoleId");
            });
like image 191
Eranga Avatar answered Sep 19 '22 02:09

Eranga