EF代码第一个错误"实体集已经定义"

C.J*_*.J. 3 c# entity-framework entity-framework-4.1

我正在使用流畅的语法来配置简单MovieGenre实体之间的M:M关系.那工作正常.

我的问题是我也希望将链接/连接表公开MovieGenre为实体.我意识到它没有必要,因为它只包含键,但我希望拥有它,因为它会使一些操作更容易.

我尝试配置链接表时收到此错误:

已定义具有模式"媒体"和表格"MovieGenre"的EntitySet"MovieGenre1".

我知道它必须与我建立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);
}
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激.谢谢.

Cos*_*nea 7

你正在尝试的是不可能的.您需要从映射中删除MovieGenre.

不要担心从数据库中获取实体只是为了将它添加到Genres列表中.如果您通过id多次加载实体,则无论如何只有一次调用DB.随着EF变得更好并且添加了二级缓存,它将正常工作并且运行良好.如果你太迫切需要,那么框架就没有任何魔力了.

如果你考虑模型的域和用户,大多数都是读取,所以没有太多的更新.除此之外,将一部电影添加到一个类型或反过来可能意味着许多事情,在这种情况下,你不应该直接公开集合,而是添加方法来实现行为.

行为的一个例子是"如果你添加超过10种类型的电影,那么电影应该将其类别改为X"以及各种其他事物.不要再考虑数据了.Domain Driven Design是一本很好的书,可以阅读这个主题.

在这种情况下,您可以将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");
           });
Run Code Online (Sandbox Code Playgroud)

查询看起来像:

// 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();
Run Code Online (Sandbox Code Playgroud)

这几乎就是你要对你的域名做的事情.