有什么办法可以写特殊的协会?

时间:2019-06-15 16:13:56

标签: c# entity-framework

我有一个名为movies的表,它具有genres列。在genres列中,我存储电影的流派ID,例如[0,5,10]类型。这些是外键,但是以不同的方式存储。有什么办法可以将这些外键与EF一起使用。

我想像List<genres> x = movie.genres一样使用它。

谢谢。

1 个答案:

答案 0 :(得分:0)

我认为,以这种方式存储流派ID会更有效。

不。保持简单,让工具(EF和数据库)执行其工作。那里已经建立了效率,无需尝试重​​新发明某些东西。首先从最简单,最标准的事情开始,然后考虑解决这些问题的替代方法,因为这些问题被证明是有效的。

就EF而言,您的电影可以引用类型的集合,您的类型可以选择引用电影的集合。通过包含MovieGenre表,该表仅包含由MovieId和GenreId组成的复合键,EF可以自动映射此关系,而无需定义MovieGenres实体。

因此,对于像这样的实体:

[Table("Movies")]
public class Movie
{
    [Key]
    public int MovieId { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Genre> Genres { get; private set; } = new List<Genre>();
}

[Table("Genres")]
public class Genre
{
    [Key]
    public int GenreId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Movie> Movies { get; private set; } = new List<Movie>();
}

然后在OnModelCreating中(或使用实体类型配置):

        modelBuilder.Entity<Movie>()
            .HasMany(x => x.Genres)
            .WithMany(x => x.Movies)
            .Map(x => x.ToTable("MovieGenres").MapLeftKey("MovieId").MapRightKey("GenreId"));

例如,当您通过“ API”将电影发送到UI或通过API发送出去时,可以根据需要展平类型信息。例如,显示在日期范围内发行的电影及其类型:

var movies = context.Movies
    .Where(x => x.ReleaseDate >= startDate && x.ReleaseDate <= endDate)
    .Select(x => new MovieViewModel
    {
        MovieId = x.MovieId,
        Name = x.Name,
        Genres = x.Genres.Select(g => new GenreViewModel {GenreId = g.GenreId, Name = g.Name).ToList()
    }).ToList();

如果您希望看到大量电影,并且UI可能会显示流派名称,但您不想为每部电影传输流派的副本:

// get genres for the applicable movies
var genres = context.Movies
    .Where(x => x.ReleaseDate >= startDate && x.ReleaseDate <= endDate)
    .SelectMany(x => x.Genres)
    .Distinct(new GenreEqualityComparer())
    .Select(x => new GenreViewModel{ GenreId = x.GenreId, Name = x.Name})
    .ToList();
// Get the movies with their Genre IDs.
var movies = context.Movies
    .Where(x => x.ReleaseDate >= startDate && x.ReleaseDate <= endDate)
    .Select(x => new MovieViewModel
    {
        MovieId = x.MovieId,
        Name = x.Name,
        GenreIds = x.Genres.Select(g => g.GenreId).ToList()
    }).ToList();

从这里,UI /消费者将了解他们对流派的需求,并可以通过ID将电影与流派相关联,而无需为每个电影记录提供过多的流派信息。再次,这可能不是必需的,但是在您可能选择大量引用相对少量和/或较大数据的情况下,您可以选择执行上述操作。