Reputation: 586
I am quite new within the .NET Entity Framework and currently, I am stuck when I am trying to implement some relationship between two entities. I am getting the following exception message:
Unable to determine the relationship represented by navigation property 'Actor.ActiveMovies' of type 'ICollection'
I do not know how I correctly identify this relationship. The movie and actor entities are shown below.
Movie.cs Entity
public class Movie
{
[Key]
public Guid MovieId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ThumbnailUrl { get; set; }
public string Language { get; set; }
[Required]
public virtual ICollection<Actor> Actors { get; set; }
}
Actor.cs Entity
public class Actor
{
[Key]
public Guid ActorId { get; set; }
public string ProfileImageUrl { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BornDate { get; set; }
public virtual ICollection<Movie> ActiveMovies { get; set; }
}
What do I want to achieve
It seems that movies and actors have a many to many relationship since a movie can have multiple actors and an actor can be active in multiple movies. Although I have not figured anything out to do this.
What have I tried
I have checked out the DatabaseContext and I thought I could implement a many to many as following.
modelBuilder.Entity<Movie>(entity =>
{
entity.HasKey(movie => movie.MovieId);
entity.Property(movie => movie.Actors).IsRequired();
entity.HasMany<Actor>(movie => movie.Actors);
});
modelBuilder.Entity<Actor>(entity =>
{
entity.HasKey(actor => actor.ActorId);
entity.HasMany<Movie>(actor => actor.ActiveMovies);
});
But this gave me the exception message
The property or navigation 'Actors' cannot be added to the entity type 'Movie' because a property or navigation with the same name already exists on entity type 'Movie'.
I would appreciate any insight in this case!
Upvotes: 1
Views: 187
Reputation: 1270
You need to fully define The relationship. In this case we are using separate table. Try this.
public class Movie
{
public Guid MovieId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ThumbnailUrl { get; set; }
public string Language { get; set; }
public virtual ICollection<MovieActor> MovieActors { get; set; }
}
public class Actor
{
public Guid ActorId { get; set; }
public string ProfileImageUrl { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BornDate { get; set; }
public virtual ICollection<MovieActor> MovieActors { get; set; }
}
public class MovieActor
{
public int MovieId { get; set; }
public Movie Movie { get; set; }
public int ActorId { get; set; }
public Actor Actor{ get; set; }
}
and in your OnModelCreating()
modelBuilder.Entity<MovieActor>()
.HasKey(x=> new { x.ActorId, x.MovieId });
modelBuilder.Entity<MovieActor>()
.HasOne(bc => bc.Movie)
.WithMany(b => b.MovieActors)
.HasForeignKey(bc => bc.MovieId);
modelBuilder.Entity<MovieActor>()
.HasOne(bc => bc.Actor)
.WithMany(c => c.MovieActors)
.HasForeignKey(bc => bc.ActorId);
Upvotes: 1
Reputation: 5512
EF core does not - yet, unfortunately - support many-to-many relationships without needing the relationship as a fully defined entity.
Coming in .net 5 and EF core 5.x is that feature which will roughly work like
builder.Entity<Movie>()
.HasMany(m=>m.Actions)
.WithMany(a=>a.Movies); // Invented syntax, the feature has not been released yet.
For the time being you'll need to define the entity which maps MovieActor manually and map both sides of the one-to-many relationship it will model. I am eliding the definition for that entity here, just going to define the configuration below.
builder.Entity<MovieActor>()
.HasKey(ma => new { ma.MovieId, ma.ActorId });
builder.Entity<Movie>()
.HasMany(m=>m.MoiveActors)
.WithOne(ma=>ma.Movie);
builder.Entity<Actor>()
.HasMany(m=>m.MoiveActors)
.WithOne(ma=>ma.Actor);
Upvotes: 0