【问题标题】:Fix the problem "unable to determine the relationship..." Entity Framework修复实体框架“无法确定关系...”的问题
【发布时间】:2022-01-05 18:42:51
【问题描述】:

我尝试创建数据库但遇到问题

无法确定“HashSet”类型的导航“Movie.Actors”所呈现的关系

我的代码有什么问题?

public class Movie
{
    [Key]
    public string Id { get; set; }
    public string Name { get; set; }
    public double Rating { get; set; }
    public HashSet<Person> Actors { get; set; }
    public Person Director { get; set; }
    public HashSet<Tag> Tags { get; set; }

    public Movie() { }

    public Movie(string id, string name, double rating, HashSet<Person> actors, Person director, HashSet<Tag> tags)
    {
        Id = id;
        Name = name;
        Rating = rating;
        Actors = actors;
        Director = director;
        Tags = tags;
    }
}

public class Person
{
    [Key]
    public string Id { get; set; }
    public string Name { get; set; }
    public HashSet<Movie> ActorMovies { get; set; }

    public Person() { }

    public Person(string id, string name)
    {
        Id = id;
        Name = name;
    }
}

class ApplicationContext: DbContext
{
    public DbSet<Movie> Movies { get; set; }
    public DbSet<Person> Persons { get; set; }
    public DbSet<Tag> Tags { get; set; }

    public ApplicationContext()
    {
        Database.EnsureCreated();
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=localhost\SQLEXPRESS;Database=Movies;Trusted_Connection=True;");
    }
 }

是关于“多对多”关系的东西吗?将不胜感激。

【问题讨论】:

  • 是关于“多对多”关系的吗? - 它实际上与许多关系有关;)

标签: c# database entity-framework entity-framework-core


【解决方案1】:

EF 正在苦苦挣扎,因为您已经将 Movie 连接到 Person 两次,一次是 Movie-has-many-Actor-Persons,一次是通过 Movie-has-one-Person-Director。对你来说,它的方向很明显,但 EF 可能会合理地看到:

  • 来自 Movie.Actors:Person.Movies 的 many:many 或
  • 来自 Movie.Director:Person.Movies 的 one:many

它无法决定。因此,您必须告诉它,以便它可以理解地图。它可能看起来像:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{
    modelBuilder.Entity<Movie>().HasMany(m => m.Actors).WithMany(p => p.ActorMovies);
    modelBuilder.Entity<Movie>().HasOne(m => m.Director);
}

没有将 Person 映射到他们拥有的董事职位的属性,但如果您确实向 Person 添加了一些 public ICollection&lt;Movie&gt; DirectedMovies { get; set; } = new HashSet&lt;Movie&gt;();,那么您可以将其指定为 .HasOne(m =&gt; m.Director).WithMany(p =&gt; p.DirectedMovies)

FWIW,您可能想将 ActorMovies 重命名为 ActedInMovies..

附注:多对多支持需要 EF5+


话虽如此,现实世界中的电影可以有不止一位导演。在我看来,我想我会建模如下:

class Person{
  ICollection<MoviePerson> Movies {get;set;}
}

class Movie{
  ICollection<MoviePerson> People {get;set;}
}

class MoviePerson{
  Movie Movie {get;set;}
  Person Person {get;set;}
  Role Role {get;set;}
}

enum Role{
  Actor,
  Director
}

它允许任意数量的任何类型的具有某些角色的人与电影相关联,并且 EF 无需任何映射指令就能够找出它

【讨论】:

    猜你喜欢
    • 2021-12-18
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 2013-07-13
    • 1970-01-01
    相关资源
    最近更新 更多