Первая ошибка кода EF "Набор сущностей уже определен" - PullRequest
3 голосов
/ 22 октября 2011

Я использую свободный синтаксис для настройки отношения M: M между простыми Movie и Genre сущностями.Это работает хорошо.

Моя проблема в том, что я также хочу представить таблицу ссылок / соединений MovieGenre также как сущность.Я понимаю, что в этом нет необходимости, поскольку он содержит только ключи, но я хочу иметь его, потому что он облегчит некоторые операции.

Я получаю эту ошибку, когда пытаюсь настроить таблицу ссылок:

EntitySet 'MovieGenre1' со схемой 'Media' и таблицей 'MovieGenre' уже был определен.

Я знаю, что это нужно сделать, когда я уже установил отношения M: M, но убежищеНе понял, как заставить все это работать вместе.

Ниже мой код:

public class Genre
{
   public int GenreID { get; set;}
   public string Name { get; set; }

   public ICollection<Movie> Movies { get; set; }
}

public class Movie
{
   public int MovieID { get; set; }
   public string Title { get; set; }

   public ICollection<Genre> Genres { get; set; }
}

public class MovieGenre
{
   public int MovieID { get; set; }
   public int GenreID { get; set; }

   public Movie Movie { get; set; }
   public Genre Genre { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   //Genre
   modelBuilder.Entity<Genre>()
               .ToTable("Genre", "Media");

   //Movie
   var movieCfg = modelBuilder.Entity<Movie>();
   movieCfg.ToTable("Movie", "Media");
   movieCfg.HasMany(m => m.Genres)
           .WithMany(g => g.Movies)
           .Map(m =>
           {
              m.MapLeftKey("MovieID");
              m.MapRightKey("GenreID");
              m.ToTable("MovieGenre", "Media");
           });

   //MovieGenres
   var movieGenresCfg = modelBuilder.Entity<MovieGenre>();
   movieGenresCfg.ToTable("MovieGenre", "Media");
   movieGenresCfg.HasKey(m => new
   {
      m.MovieID, m.GenreID
   });

   base.OnModelCreating(modelBuilder);
}

Любая помощь будет оценена.Спасибо.

1 Ответ

6 голосов
/ 22 октября 2011

То, что вы пытаетесь, невозможно. Вам необходимо удалить MovieGenre из сопоставления.

Не беспокойтесь о получении объекта из базы данных, просто чтобы добавить его в список жанров. Если вы загружаете сущность по идентификатору несколько раз, в любом случае происходит только один вызов БД. По мере улучшения EF и добавления кеша второго уровня он будет работать и работать хорошо. Если вы слишком императивны, у вас не останется магии.

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

Одним из примеров поведения может быть «если вы добавите фильм в более чем 10 жанров, то фильм должен изменить, скажем, свою категорию на X», и всякие другие вещи. Хватит думать только о данных. Domain Driven Design - хорошая книга для чтения на эту тему.

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

    public class Genre
    {
       public int GenreID { get; set;}
       public string Name { get; set; }
    }

    public class Movie
    {
       public int MovieID { get; set; }
       public string Title { get; set; }

       public ICollection<Genre> Genres { get; set; }
    }
....

    //Movie
   var movieCfg = modelBuilder.Entity<Movie>();
   movieCfg.ToTable("Movie", "Media");
   movieCfg.HasMany(m => m.Genres)
           .WithMany()
           .Map(m =>
           {
              m.MapLeftKey("MovieID");
              m.MapRightKey("GenreID");
              m.ToTable("MovieGenre", "Media");
           });

Запросы будут выглядеть так:

// get all movies for a particular genre
var movies = movieContext.Movies.Where(m => m.Genres.Any(g => g.GenreID = id))
                                .OrderBy(m => m.Name)
                                .ToList();

// get all movies 
var movies = movieContext.Movies.OrderBy(m => m.Name).Take(10).ToList();

Это почти все, что вы собираетесь делать со своим доменом.

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