0

There are two different models in my project: Movie and Actor. Movie has a list of actors and Actor has a list of movies. What I want to do is given a movie, get all of the actors, and then for each actor examine their movies acted in.

So, to get the information, I use:

var movie = context.Movies.Include("Cast.ActingCredits").FirstOrDefault(m => m.Key == key);

The problem is that while the list ActingCredits is not null, there are no values in it. Is there something that I am missing to load the values in the list? ActingCredits is an ICollection<Movie>.

 public class Actor : ModelBase
 {
     public ICollection<Movie> ActingCredits { get; set; }
 }

public class Movie : ModelBase
{
    public string Title { get; set; }
    public DateTime Year { get; set; }
    public Genre Genre { get; set; }
    public int RunTime { get; set; }
    public int Sales { get; set; }
    public ICollection<Actor> Cast { get; set; }
}

EDIT: It has come to my attention that this may be wrong and is the cause of the issue.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Movie>().HasMany(p => p.Cast).WithMany();
        modelBuilder.Entity<Actor>().HasMany(m => m.ActingCredits).WithMany();
    }
6
  • Post the structure of the actor and movie classes? Commented Jun 5, 2017 at 17:24
  • what is key / m.Key? Commented Jun 5, 2017 at 17:30
  • The key value is in the ModelBase class and it is an int with the attribute [Key]. Key is the movie key I want to get, m.Key is the key of the given movie. Commented Jun 5, 2017 at 17:34
  • 1
    Can't reproduce, it works as expected for me (EF6.1.3) Commented Jun 5, 2017 at 18:15
  • Does context.Actors.Include("ActingCredits") work as expected? Commented Jun 5, 2017 at 18:55

3 Answers 3

1

You are not typing the correct name of the property in the include. Try this:

    var movie = context.Movies.Include("Cast").FirstOrDefault(m => m.Key == key);

Also, make sure that your database is populated before executing this. I tested this and it works, it retrieves everything.

Sign up to request clarification or add additional context in comments.

5 Comments

I thought the include was for the adding the a collection/different table to the query. In this case Movie has Cast, so we want to include Cast, right? That code above throws a 500 internal server error, "A specified Include path is not valid"
When I just have Include("Cast") it says that ActingCredits is null. I know that the list of acting credits is full because I can call Get on Actors/ActingCredits and it returns a full list of movies.
I think your problem is in the way you modeled your database. If you are not getting any movies per cast retrieved from movie then that means you don't have the appropriate relations (key/foreign keys) in place in the database.
I added some of the code the database uses to create relationships with. Is what I have wrong?
There is no need for you to specify the relations with the Fluent Api. The Code First model will be properly created without it. Try removing it and add some movies with actors in the database.
1

The problem was with the database and how I initialized it.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Movie>().HasMany(p => p.Cast).WithMany(p => p.ActingCredits);
        modelBuilder.Entity<Actor>().HasMany(m => m.ActingCredits).WithMany(m => m.Cast);

    }

Thanks to all who commented. I believe I understand entity framework a whole lot more now.

2 Comments

Cool. As a rule of thumb, never duplicate relationship configuration. The relationship (in contrast with entity) has 2 ends (entities) and should be configured once (to avoid errors - the above two lines do exactly one and the same) and should reflect exactly the presence\absence of the navigation property in the With method (respectively with/without argument), otherwise by convention EF will create 2 relationships in the place where you need just one :)
Thanks for that insight. I had a feeling I did not need both lines, but I could not find a concrete example that stated so.
0

I suggest adding this:

using System.Data.Entity;

And then you can do the Include with strongly typed variables

var movie = context.Movies.Include(r => r.Cast)

However what I think you really want is to use Select instead of Include?

var movie = context.Movies.Select(r => r.Cast).SelectMany(r => r.ActingCredits);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.