zerk
zerk

Reputation: 586

Unable to determine the relationship

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

Answers (2)

AVTUNEY
AVTUNEY

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

Tanveer Badar
Tanveer Badar

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

Related Questions