1
votes

So i'm developing a basic project which uses Entity Framework Core to create a database that fetches information from TMDB based on whatever movie I enter to try and understand the whole thing better.

I've been stuck for a while trying to implement a Many-to-Many relationship between my Movie and Studio models.

Movies can have many studios attributed to them, but there are also many movies that will be connected to the studios, so it's the clear relationship to use. Below are snippets from those models:

public class Movies
{
    [Key]
    public int MovieID { get; set; }
    public ICollection<MovieStudios> MovieStudios { get; set; } = new List<MovieStudios>();
}
public class Studios
{
    [Key]
    public int StudioID { get; set; }
    public ICollection<MovieStudios> MovieStudios { get; set; } = new List<MovieStudios>();
}

And here is the join table that i've got

public class MovieStudios
{
    public int MovieID { get; set; }
    public Movies Movie { get; set; }
    public int StudioID { get; set; }
    public Studios Studio { get; set; }
}

And here is my DbContext class: public class MyDbContext : DbContext { public DbSet TblMovies { get; set; } public DbSet TblStudios { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder option)
    {
        option.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB; Database=ServerDatabase ; Trusted_Connection=True;");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MovieStudios>()
            .HasKey(bc => new { bc.MovieID, bc.StudioID });
    }
}

What I want to do, in one of my services, is return List so that I can link these studios to the movie in question when a movie is added to the database, but i'm just completely lost as for what to do. Sorry if this is a noob question, of if this is too long, just feel completely lost!

EDIT: To be more specific, I pass through the TMDB id of a film to a service i've created that returns a list of the ids of the films production studios e.g.('46226', '6735'), which is then saved in my database and also returns the index number of my Studio database so that it can be added to my film. ('1', '4', '6'). I've stored this as a List and am stuck as to how I can add these studio ids to the film i'm trying to add to the database. All examples i've seen don't really address what i'm trying to do. I'm trying to add Many studios to the one film.

2

2 Answers

1
votes

The correct way to do it is this one:

// define composite key for MovieStudios
modelBuilder
    .Entity<MovieStudios>()
    .HasKey(ct => new {ct.MovieId, ct.StudioId});

// setup one-to-many relationship MovieStudios-Movies
modelBuilder.Entity<MovieStudios>()
    .HasOne(movieStudio => movieStudio.Movie)
    .WithMany(movie => movie.MovieStudios)
    .HasForeignKey(movieStudio => movieStudio.MovieId);

// setup one-to-many relationship MovieStudios-Studios
modelBuilder.Entity<MovieStudios>()
    .HasOne(movieStudio => movieStudio.Studio)
    .WithMany(studio => studio.MovieStudios)
    .HasForeignKey(movieStudio => movieStudio.StudioId);

A many-to-many relationship between Movies and Studios is equivalent to two one-to-many relationships between MovieStudios (relationship table) and Movies and Studios respectively.

Edit:

You can add movies to a studio like this:

public async Task AddMoviesToStudioAsync(List<Movie> movies, int studioId) 
{
    var movieStudiosList
        = movies.Select(
            movie => new MovieStudios
            {
                MovieId = movie.Id, 
                StudioId = studioId
            })
            .ToList();

    await DbContext.Set<MovieStudios>().AddRangeAsync(movieStudiosList);
}
1
votes

If you want to add Many studios to the one film, you could try to use a for looping.

Try to the code shown below in your action

public async Task<IActionResult> AddStudiosToMovie(int  movieID, List<int> studioIdList)
    {
       for(int i=0;i<studioIdList.Count();i++)
        {
            var movieToStudio = new MovieStudios
            {
                MovieID = movieID,
                StudioID = studioIdList[i]
            };
            _context.Add(movieToStudio);
            await _context.SaveChangesAsync();
        }

        return RedirectToAction(nameof(Index));

    }