Emre Sert
Emre Sert

Reputation: 330

Make mapping relationship to three table using EF CodeFirst

I am student developer at C#. I have a question while making relationship to 3 tables. My tables are like this.

 public class ImdbContext : DbContext
    {
        public DbSet<Cast> Cast { get; set; }
        public DbSet<CastRole> CastRole { get; set; }
        public DbSet<Movie> Movie { get; set; }
        public DbSet<MovieCastRoleMapping> MovieCastRoleMapping { get; set; }

        public ImdbContext() : base("ImdbDbContext")
        {
        }
    }

    [Table("Movies")]
    public class Movie
    {
        [Key]
        public int movieId { get; set; }
        public string movieName { get; set; }
        public string movieYear { get; set; }
        public string movieLink { get; set; }
        public string movieImageUrl { get; set; }
        public virtual MovieCastRoleMapping MovieCastRoleMapping { get; set; }
    }
    [Table("CastRoles")]
    public class CastRole
    {
        [Key]
        public int castRoleId { get; set; }
        public string castRoleName { get; set; }

        public virtual MovieCastRoleMapping MovieCastRoleMapping { get; set; }
    }
    [Table("Casts")]
    public class Cast
    {
        [Key]
        public int castId { get; set; }
        public string nameSurname { get; set; }
        public string biography   { get; set; }

        public virtual MovieCastRoleMapping MovieCastRoleMapping { get; set; }

    }

I did not find a clear solution to make correct relation for 3 tables. When I tried to make it myself, I facing an eror like this:

The ForeignKeyAttribute on property 'fkCastId' on type 'ImdbEntity.Models.MovieCastRoleMapping' is not valid. The navigation property 'castId' was not found on the dependent type 'ImdbEntity.Models.MovieCastRoleMapping'. The Name value should be a valid navigation property name.

I know I need to set navigation property. Untill now, I was using EF DbFirst but I want to make it EF CodeFirst without using a diagram. Could you help me for fallowing class correctly ?

[Table("MovieCastRoleMappings")]
public class MovieCastRoleMapping
{
    [ForeignKey("castId")]
    public int fkCastId { get; set; }
    [ForeignKey("castRoleId")]
    public int fkCastRoleId { get; set; }
    [ForeignKey("movieId")]
    public int fkMovieId { get; set; }
}

Upvotes: 0

Views: 166

Answers (3)

Emre Sert
Emre Sert

Reputation: 330

public class ImdbContext : DbContext
{
    public DbSet<Cast> Cast { get; set; }
    public DbSet<CastRole> CastRole { get; set; }
    public DbSet<Movie> Movie { get; set; }
    public DbSet<MovieCastRoleMapping> MovieCastRoleMapping { get; set; }

    public ImdbContext() : base("ImdbDbContext")
    {
    }
}

[Table("Movies")]
public class Movie
{
    [Key]
    public int movieId { get; set; }
    public string movieName { get; set; }
    public string movieYear { get; set; }
    public string movieLink { get; set; }
    public string movieImageUrl { get; set; }
}

[Table("CastRoles")]
    public class CastRole
    {
        [Key]
        public int castRoleId { get; set; }
        public string castRoleName { get; set; }   
    }

[Table("Casts")]
public class Cast
{
    [Key]
    public int castId { get; set; }
    public string nameSurname { get; set; }
    public string biography   { get; set; }
}

[Table("MovieCastRoleMappings")]
public class MovieCastRoleMapping
{
    [Key, Column(Order = 1)]
    public int fkCastId { get; set; }
    [ForeignKey("fkCastId")]
    public virtual Cast Cast { get; set; }

    [Key, Column(Order = 2)]
    public int fkCastRoleId { get; set; }
    [ForeignKey("fkCastRoleId")]
    public virtual CastRole CastRole { get; set; }

    [Key, Column(Order = 3)]
    public int fkMovieId { get; set; }
    [ForeignKey("fkMovieId")]
    public virtual Movie Movie { get; set; }
}

That's for the solution. Thanks for your interesting.

Upvotes: 0

Steve Greene
Steve Greene

Reputation: 12304

You are missing the navigation properties and using the attribute wrong:

[Table("MovieCastRoleMappings")]
public class MovieCastRoleMapping
{
    [Key, Column(Order = 0)]
    public int fkCastId { get; set; }
    [ForeignKey("fkCastId")]
    public Cast Cast { get; set; }

    [Key, Column(Order = 1)]
    public int fkCastRoleId { get; set; }
    [ForeignKey("fkCastRoleId")]
    public CastRole CastRole { get; set; }

    [Key, Column(Order = 2)]
    public int fkMovieId { get; set; }
    [ForeignKey("fkMovieId")]
    public Movie Movie { get; set; }
}

Upvotes: 1

Hadi Samadzad
Hadi Samadzad

Reputation: 1540

FluentAPI gives more features to implement navigation properties in code-first approach. The below code implements a one-to-many relationship between Movie and Cast and a one-to-one relationship between Cast and CastRole:

public class Movie
{
    public int movieId { get; set; }
    public string movieName { get; set; }
    public string movieYear { get; set; }
    public string movieLink { get; set; }
    public string movieImageUrl { get; set; }

    public virtual List<Cast> Casts { get; set; }
}

public class Cast
{
    public int castId { get; set; }
    public string nameSurname { get; set; }
    public string biography   { get; set; }

    public int MovieId { get; set;}
    public virtual Movie Movie { get; set; }

    public int CastRoleId { get; set;}
    public virtual CastRole CastRole { get; set; }

}

public class CastRole
{
    public int castRoleId { get; set; }
    public string castRoleName { get; set; }

    public virtual Cast Cast { get; set; }
}



public class ImdbContext : DbContext
{
    public DbSet<Cast> Casts { get; set; }         // Table name will be "Casts"
    public DbSet<CastRole> CastRoles { get; set; } // Table name will be "CastRoles"
    public DbSet<Movie> Movies { get; set; }       // Table name will be "Movies"

    public ImdbContext() : base("ImdbDbContext")
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Setting primary keys
        modelBuilder.Entity<Movie>()
                    .HasKey<int>(x => x.movieId);
        modelBuilder.Entity<Cast>()
                    .HasKey<int>(x => x.castId);
        modelBuilder.Entity<CastRole>()
                    .HasKey<int>(x => x.castRoleId);

        modelBuilder.Entity<Movie>()
                    .HasMany<Cast>(x => x.Casts)
                    .WithRequired(s => s.Movie)
                    .HasForeignKey<int>(x => x.MovieId);

        modelBuilder.Entity<Cast>()
                    .HasRequired(x => x.CastRole)
                    .WithRequiredPrincipal(x => x.Cast);

        // Creating Model
        base.OnModelCreating(modelBuilder);
    }

}

Upvotes: 1

Related Questions