6

How can I make many to many relation between AspNetRoles from Identity 3.0 and my custom table? I want simple 3 table, with both PermissionId and RoleId, something like AspNetUsersRole. I have something like this:

public class Permission
{
    public int PermissionId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<ApplicationRole> Roles { get; set; }
}

public class ApplicationRole : IdentityRole
{
    public virtual ICollection<Permission> Permissions { get; set; }
}

But when I want to add migration, I got error:

 Unable to determine the relationship represented by navigation property 'ApplicationRole.Permissions' of type 'ICollection<Permission>'. Either manually configure the relationship, or ignore this property from the model. 
Fikoblin
  • 63
  • 1
  • 5
  • Possible duplicate of [How to create a many to many relationship with latest nightly builds of EF7?](http://stackoverflow.com/questions/29442493/how-to-create-a-many-to-many-relationship-with-latest-nightly-builds-of-ef7) – Abrar Jahin Dec 14 '16 at 06:55

3 Answers3

10

EF Core (EF7) does not currently support many to many relationship without a join entity. (Reference)

So, what you should do is to create an entity class for the join table and mapping two separate one-to-many relationships. Like;

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<PostTag>()
        .HasKey(t => new { t.PostId, t.TagId });

    modelBuilder.Entity<PostTag>()
        .HasOne(pt => pt.Post)
        .WithMany(p => p.PostTags)
        .HasForeignKey(pt => pt.PostId);

    modelBuilder.Entity<PostTag>()
        .HasOne(pt => pt.Tag)
        .WithMany(t => t.PostTags)
        .HasForeignKey(pt => pt.TagId);
}

public class PostTag
{
        public int PostId { get; set; }
        public Post Post { get; set; }

        public string TagId { get; set; }
        public Tag Tag { get; set; }
}
Emre Bolat
  • 4,316
  • 5
  • 29
  • 32
3

Regarding to this question answer, it can be done more easily like this-

class Photo
{
    public int Id { get; set; }
    public ICollection<PersonPhoto> PersonPhotos{ get; set; }
}

class PersonPhoto
{
    public int PhotoId { get; set; }
    public Photo Photo { get; set; }

    public int PersonId { get; set; }
    public Person Person { get; set; }
}

class Person
{
    public int Id { get; set; }
    public ICollection<PersonPhoto> PersonPhotos{ get; set; }
}

Be sure to configure PersonPhoto with a composite key:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<PersonPhoto>().HasKey(x => new { x.PhotoId, x.PersonId });
}

To navigate, use a Select:

// person.Photos
var photos = person.PersonPhotos.Select(c => c.Photo);
Community
  • 1
  • 1
Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161
2

Add This namespace-

using Microsoft.AspNetCore.Identity;


public class Permission
{
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public int PermissionId { get; set; }
     public string Name { get; set; }
     public string UserIdFK { get; set; } //Foreign Key of Identity tbl

     [ForeignKey("UserIdFK")]
     public IdentityUser UserDetail { get; set; }
}

That's it, Happy coding :)

panky sharma
  • 2,029
  • 28
  • 45