Skip to content

Easy way to create Many To Many relationship in Entity Framework

Notifications You must be signed in to change notification settings

ZBAGI/EntityFramework-ManyToMany

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 

Repository files navigation

EntityFramework Many-To-Many relationship

Currently EntityFramework doas not support Many-To-Many relationship. In order to achieve such us relation joint entity is needed. That creates uncoforable sytuation in which we have to constantly deal with aditional 'middleman' entity that usually serves no other porpues then satisfy Entity Framework. This project aims to show how to use JointCollectionFacade.cs that will manage joints entities automatically. So dealing with many-to-many relationship is as easy as using ICollection.

Example uses MySQL provider for EntityFrameworkCore named Pomelo with lazy loading proxies. To run it, just change database credentials.

Lazy-loading

  • Please notice that in order to populate Facade, joint entity with it's properties has to be included. In example lazy-load proxies loading it automatically. Without proxies inclusion have to be done manually otherwise property Roles will be empty.
DbSet<User> Users = DatabaseContext.Accounts;
var usersWithRoles = Users.Include(u => u.UserRoleJoints).ThenInclude(j => j.Role).ToList();

OData implementation

In order to correctly $expand collection facade i recommend to use DTO's with AutoMapper which will help with loading facade without exposing joint entity in EDM model.

Here is how to create EdmModel for DTO:

var builder = new ODataConventionModelBuilder();
var userType= builder.AddEntityType(UserDTO);
userType.Name = nameof(User); // I like to hide the fact it is DTO, at the end every entity in EDM should be DTO so adding sufix into every entry is pointless.
builder.AddEntitySet("Users", userType);

Here is example of AutoMapper config:

new MapperConfiguration(cfg =>
{
    cfg.CreateMap<User, UserDto>()
        .ForMember(dto => dto.Roles,
            opt => opt.MapFrom(a => a.UserRoleJoints.Select(j => j.Role).AsQueryable()));
});

And finally the controller:

[EnableQuery]
public IEnumerable<UserDto> Get()
{
    DbSet<User> users = Database.Users;
    return Mapper.ProjectTo<UserDto>(users);
} 

About

Easy way to create Many To Many relationship in Entity Framework

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages