使用 EF Code First 与三个 table 建立映射关系

Make mapping relationship to three table using EF CodeFirst

我是 C# 的学生开发人员。我在与 3 个表建立关系时有一个问题。我的桌子是这样的

 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; }

    }

我没有找到明确的解决方案来为 3 个表建立正确的关系。当我尝试自己制作时,我遇到了这样的错误:

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.

我知道我需要设置导航属性。直到现在,我一直在使用 EF DbFirst,但我想在不使用图表的情况下使其成为 EF CodeFirst。你能帮我正确休假 class 吗?

[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; }
}

您缺少导航属性并且使用了错误的属性:

[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; }
}

FluentAPI 提供了更多功能来以代码优先的方式实现导航属性。下面的代码实现了 MovieCast 之间的一对多关系以及 CastCastRole 之间的一对一关系:

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);
    }

}
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; }
}

这就是解决方案。谢谢你的有趣。