Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF代码第一个错误“;已定义实体集";_C#_Entity Framework_Entity Framework 4.1 - Fatal编程技术网

C# EF代码第一个错误“;已定义实体集";

C# EF代码第一个错误“;已定义实体集";,c#,entity-framework,entity-framework-4.1,C#,Entity Framework,Entity Framework 4.1,我使用流畅的语法在简单的Movie和Genre实体之间配置m:m关系。没问题 我的问题是,我还希望将link/join表MovieGenre作为一个实体公开。我意识到这是没有必要的,因为它只包含键,但我希望有它,因为它将使一些操作更容易 我在尝试配置链接表时遇到此错误: 具有架构“Media”和表“MovieGenre”的实体集“MovieGenre1” 已经定义了 我知道这是必须的,因为我已经建立了M:M关系,但还没有弄清楚如何让这一切一起工作 下面是我的代码: public class Ge

我使用流畅的语法在简单的
Movie
Genre
实体之间配置m:m关系。没问题

我的问题是,我还希望将link/join表
MovieGenre
作为一个实体公开。我意识到这是没有必要的,因为它只包含键,但我希望有它,因为它将使一些操作更容易

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

具有架构“Media”和表“MovieGenre”的实体集“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);
}
公共类体裁
{
public int GenreID{get;set;}
公共字符串名称{get;set;}
公共ICollection电影{get;set;}
}
公映
{
public int MovieID{get;set;}
公共字符串标题{get;set;}
公共ICollection类型{get;set;}
}
公共类电影流派
{
public int MovieID{get;set;}
public int GenreID{get;set;}
公共电影{get;set;}
公共类型{get;set;}
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
//体裁
modelBuilder.Entity()
.ToTable(“流派”、“媒体”);
//电影
var movieCfg=modelBuilder.Entity();
movieCfg.ToTable(“电影”、“媒体”);
movieCfg.HasMany(m=>m.tyres)
.有很多(g=>g.电影)
.Map(m=>
{
m、 MapLeftKey(“电影ID”);
m、 MapRightKey(“GenreID”);
m、 ToTable(“电影类型”、“媒体”);
});
//电影类型
var movieGenresCfg=modelBuilder.Entity();
movieGenresCfg.ToTable(“电影流派”、“媒体”);
movieGenresCfg.HasKey(m=>new
{
m、 电影ID,m.GenreID
});
基于模型创建(modelBuilder);
}

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

您正在尝试的是不可能的。您需要从映射中删除您的电影类型

不要担心从数据库中获取实体只是为了将其添加到类型列表中。如果多次按id加载实体,则只需调用一次DB。随着EF变得更好,并添加了二级缓存,它将正常工作并表现良好。如果您过于迫切,那么框架就没有魔力了

如果你考虑到你的模型的域和用户,大多数都是读的,所以没有太多的更新。最重要的是,将电影添加到一种类型或其他方式可能意味着很多事情,在这种情况下,您不应该直接公开收藏,而应该添加实现行为的方法

行为的一个例子是“如果你将一部电影添加到10种以上的类型,那么该电影应该将其类别更改为X”以及其他各种事情。不要只考虑数据。这是一本关于这个主题的好书

在这里,你可以将电影实体视为根聚合,因为电影是你的用户所追求的,电影是你要编辑的管理员。一部电影可能不存在流派,所以流派只是电影的一个标签,一个价值对象,并不是很重要。您的映射将变成:

    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");
           });

这几乎是您在域中要做的所有事情。

您是否首先使用EF的模型?我只能说,当使用“db优先”方法时,纯“连接”表(仅两个外键)不会传输到特定实体。只有在向连接表中添加一些其他字段时,才会将其转换为实体模型中的特定实体。如果希望将连接表作为实体公开,则必须更改
电影
类型
实体。
Movie
实体将有一个
MovieGenres
集合,而不是
Genres
Genres
实体将有一个
MovieGenres
集合,而不是
Movies
。您也必须通过加入实体访问列表(例如,
myMovie.MovieGenres.Select(mg=>mg.Genre)
,而不仅仅是
myMovie.Genres
)。我不明白这怎么会让事情变得容易。将联接表作为实体公开的唯一原因是,它包含的不仅仅是FKs(这不是您的情况)。@Joep这是我正在使用的第一个代码。@Yakimych您可能是对的,但我的想法是,如果您有一个电影ID和该电影的GenreID集合,那么直接与联接表一起工作会很方便。我不喜欢通过查询DB来获取每个genreID的流派实体,然后将其添加到电影集合中。此外,如果联接表中确实包含其他数据,则代码不会中断。
// 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();