user4940368
user4940368

Reputation:

Get property's property

My classes are designed like that:

public class Video {
    public int Id {get; set;}
    public string Title {get; set;}

    public int PlaylistId {get; set;}
    [ForeignKey("PlaylistId")]
    public Playlist Playlist {get; set;}
}

public class Playlist {
    public int Id {get; set;}
    public string Description {get; set;}

    public List<Video> Videos {get; set;}

    public Playlist() {
        Videos = new List<Video>();
    }
}

And now, lets create some objects:

Video video = new Video();
video.Title = "Titanic";

Playlist playlist = new Playlist();
playlist.Description = "Best videos";
playlist.Videos.Add(video);

context.Playlists.Add(playlist);
context.SaveChanges();

The problem is I cant get video.Playlist reference from my database context. Of course I could add a method for getting wanted property:

public static Playlist GetPlaylist(int videoId) {
    using (var context = new DatabaseContext()) {
        Video video = context.Videos.FirstOrDefault(x => x.Id == videoId);
        return context.Playlists.FirstOrDefault(x => x.Id == video.PlaylistId);
    }
}

But I think there must be a better solution. Can you help me with that?

Upvotes: 0

Views: 63

Answers (2)

Slava Utesinov
Slava Utesinov

Reputation: 13488

Try to correct your class declarations (virtual and ICollection). Also ensure that context.Configuration.LazyLoadingEnabled = true;:

public class Video 
{
    public int Id {get; set;}
    public string Title {get; set;}

    public int PlaylistId {get; set;}
    [ForeignKey("PlaylistId")]
    public virtual Playlist Playlist {get; set;}
}

public class Playlist 
{
    public int Id {get; set;}
    public string Description {get; set;}

    public virtual ICollection<Video> Videos {get; set;}
}

Upvotes: 1

grek40
grek40

Reputation: 13438

If you want to select specific things, you can just select them:

var playlist = context.Videos
                   .Where(x => x.Id == videoId)
                   .Select(x => x.Playlist)
                   .FirstOrDefault();

You can also use Include to specify referenced entities to be loaded

var video = context.Videos
                   .Include(x => x.Playlist)
                   .FirstOrDefault(x => x.Id == videoId);
var playlist = video.Playlist;

The third option would be virtual and lazy-loading as @SlavaUtesinov answered. But if you know beforehand that you want the playlist, there is no need for lazy loading, it would just create unnecessary intermediate queries.

Lazy loading would be a good way in case you want to load a list of videos and you only want to access the playlists for some of the videos, not most/all of them.

Upvotes: 0

Related Questions