Question

I'd like to add a table to define permission object than can be applied to many models. To do this, I create a Permission class:

public class Permission
{
    [Key]
    int PermissionID {get; set;}
    string User {get; set;}
    bool Read {get; set;}
    bool Write {get; set;}
}

And then other object classes than can have a List of Permission:

public class ObjectModel1
{
    [Key]
    int idObject1 {get; set;}
    ... Other properties ...
    public virtual ICollection<Permission> Permission {get; set;}
}

public class ObjectModel2
{
    [Key]
    int idObject2 {get; set;}
    ... Other properties ...
    public virtual ICollection<Permission> Permission {get; set;}
}

How can I obtaint a multiple many to many relationship between Permission and other Object classes without defining Foreign Keys in Permission class for each Object?

Was it helpful?

Solution

A many to many relationship will have an xref table between the two entities:

// because Permission has a collection to ObjectModel1 and ObjectModel1 has a collection
// to permission, it is treated as a many to many relationship with an implicit
// xref between the tables. The xref will contain a foreign key to each entity that is
// also a composite primary key
public class Permission
{
    [Key]
    int PermissionID {get; set;}
    string User {get; set;}
    bool Read {get; set;}
    bool Write {get; set;}

    public virtual ICollection<ObjectModel1> ObjectModel1s { get; set; }
    public virtual ICollection<ObjectModel2> ObjectModel2s { get; set; }
}

public class ObjectModel1
{
    [Key]
    int idObject1 {get; set;}
    ... Other properties ...
    public virtual ICollection<Permission> Permission {get; set;}
}

public class ObjectModel2
{
    [Key]
    int idObject2 {get; set;}
    ... Other properties ...
    public virtual ICollection<Permission> Permission {get; set;}
}

Entity Framework will create a table that is something like PermissionObjectModel1 that has a composite primary key with two foreign keys (one to Permission, one to ObjectModel1). It will create another table for ObjectModel2 with similar keys. The foreign key doesn't exist on Permission itself.

If you don't want to have the navigation property on permission, then I think you will need to use the Fluent API:

public class MyDbContext : DbContext
{
    public DbSet<Permission> Permissions { get; set; }
    public DbSet<ObjectModel1> ObjectModel1s { get; set; }
    public DbSet<ObjectModel2> ObjectModel2s { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ObjectModel1>()
            .HasMany(many => many.Permissions)
            .WithMany() // dont want navigation property on Permission
            .Map(xref => xref.MapLeftKey("ObjectModel1Id")
                             .MapRightKey("PermissionId")
                             .ToTable("ObjectModel1PermissionXref"));

        modelBuilder.Entity<ObjectModel2>()
            .HasMany(many => many.Permissions)
            .WithMany() // dont want navigation property on Permission
            .Map(xref => xref.MapLeftKey("ObjectModel2Id")
                             .MapRightKey("PermissionId")
                             .ToTable("ObjectModel2PermissionXref"));
    }
}

Something similar to the above code would still give you a many to many relationship, but the navigation property would not be defined on Permission.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top