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

时间:2011-10-21 21:08:56

标签: c# entity-framework entity-framework-4.1

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

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

当我尝试配置链接表时出现此错误:

  

具有架构'Media'和表'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);
}

任何帮助将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:6)

你正在尝试的是不可能的。您需要从映射中删除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");
           });

查询看起来像:

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

这几乎与您的域名有关。