Есть ли способ написать специальную ассоциацию? - PullRequest
1 голос
/ 15 июня 2019

У меня есть таблица с именем movies и столбцом genres. В столбце genres я храню идентификатор жанра фильма как [0,5,10] type. Это внешние ключи, но они хранятся по-другому. Есть ли способ использовать эти внешние ключи с EF.

Я хочу использовать его как List<genres> x = movie.genres.

Спасибо.

1 Ответ

0 голосов
/ 17 июня 2019

" Я думал, что хранение идентификаторов жанров может быть более эффективным. "

Нет.Сохраняйте это простым и позвольте инструментам (EF и Database) делать то, что они делают.Эффективность уже построена, не нужно пытаться что-то изобретать заново.Начните с самой простой, самой стандартной вещи, затем посмотрите на альтернативы для решения проблем, поскольку эти проблемы доказаны как действительные.

Что касается 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, например, и вы можете сгладить информацию о жанре, как вы считаете нужным.Например, для отображения фильмов, выпущенных в диапазоне дат с их жанрами:

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

Если вы ожидаете большой список фильмов и пользовательский интерфейс может отображать название жанра, но вы не хотите передаватькопии жанра для каждого фильма:

// 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();

Отсюда пользовательский интерфейс / потребитель узнает, что им нужно в жанрах, и может связать фильмы с жанром по идентификатору без лишней полезной нагрузки.повторная информация о жанре для каждой записи фильма.Опять же, в этом может не быть необходимости, но в тех случаях, когда вы можете выбирать множество ссылок на сравнительно небольшое и / или большое количество данных, у вас есть возможность сделать что-то подобное выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...