How to retrieve many to many (N-N) data from WCF RIA services

Download Demo project ManyToMany.zip

This tutorial shows how to retrieve Many-to-Many data in a Silverlight RIA Application. Here is our data model:

data model

I want to show a list of movies and each movie contains actors:

movies

Set up your project

The following things are pretty common for a typical Silverlight Business Application:

-=> BUILD THE PROJECT <=–

The following step is to retrieve data in the ViewModel

public MainViewModel()
{
    var context=new MovieDomainContext();
    var lo = context.Load<Movie>(context.GetMovieQuery());
    lo.Completed += delegate
    {
        Movies =new ObservableCollection<Movie>( lo.Entities);
        OnPropertyChanged("Movies");
    };
}

The default behavior is that only the movies are retrieved. No surprises here. But how do we get the Actors?

Get more data

Open the DomainService and add a method:

public IQueryable<Movie> GetMovieWithActors()
{
    return this.ObjectContext.Movie.Include("MovieActor.Actor");
}

As you can see, the syntax for the Include method is: Include(“Table1.Table2”)

Open DomainService.metadata and find the properties that should include child entities. Add an [Include] attribute to them:

internal sealed class MovieMetadata
{

    // Metadata classes are not meant to be instantiated.
    private MovieMetadata()
    {
    }

    [Include] // HERE.......
    public EntityCollection<MovieActor> MovieActor { get; set; }

    public int MovieId { get; set; }

    public string Name { get; set; }
}

internal sealed class MovieActorMetadata
{

    // Metadata classes are not meant to be instantiated.
    private MovieActorMetadata()
    {
    }

    [Include] // AND HERE......
    public Actor Actor { get; set; }

    public int ActorId { get; set; }

    public Movie Movie { get; set; }

    public int MovieActorId { get; set; }

    public int MovieId { get; set; }
}

Open your ViewModel and use the GetMovieWithActors query:

public MainViewModel()
{
    var context=new MovieDomainContext();
    var lo = context.Load<Movie>(context.GetMovieWithActorsQuery());
    lo.Completed += delegate
    {
        Movies =new ObservableCollection<Movie>( lo.Entities);
        OnPropertyChanged("Movies");
    };
}

If you place a breakpoint on the OnPropertyChanged line, you can see that the Movies collection holds a list of MovieActors and each MovieActor holds an Actor entity.