gilpach
gilpach

Reputation: 1385

Automapper and Linq with joined tables, populating ViewModel properties

Having just figured out how to populate my ViewModel from a model using Automapper, I am now onto the next challenge – populating the ViewModel properties from a joined table.

The image below depicts my simple database.

enter image description here

My ViewModel class is defined as:

public class PersonViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Nullable<int> Age { get; set; }
    public Nullable<int> SuffixId { get; set; }
    public string PersonStatus { get; set; }
    public string PersonPreference { get; set; }

    public virtual Suffix Suffix { get; set; }
}    enter code here

Note the additional fields of PersonStatus and PersonPreference that will come from joining PersonInfo to Person. Here is the code I use to instantiate my mapping configuration:

        Mapper.CreateMap<PersonViewModel, Person>();
        Mapper.CreateMap<Person, PersonViewModel>();

And now the code to populate the ViewModel

        List<PersonViewModel> persons = null;
        using (var context = new DemoEntities())
        {
            persons = (from p in context.People.AsEnumerable()
                       join i in context.PersonInfoes on p.Id equals i.PersonId
                    select Mapper.Map<PersonViewModel>(p)).ToList();
            return persons;
        }

How would I populate the two joined properties (PersonStatus and PersonPreference) from this setup?

Thanks in advance!

Upvotes: 2

Views: 6329

Answers (1)

Gert Arnold
Gert Arnold

Reputation: 109220

AutoMapper can automatically flatten an object structure if the source and target classes meet some requirements.

  • The source class, the class that the mapping starts from, should have reference property to the related class. In you case: Person.PersonInfo (1:1, but n:1 will also work).1
  • The target class should contain property names that allow AutoMapper to resolve the property path to the referenced object. in your case: PersonViewModel.PersonInfoStatus, so AutoMapper will see that there's a property PersonInfo in the source object and a property Status in the referenced object.

If you've got these things in place, you can do

persons = context.People.Project().To<PersonViewModel>().ToList();

The Project().To syntax is a relatively new API that allows working on IQueryables. For more details see Does AutoMapper support Linq?.

You will see that this sends a JOIN query to the database.


1AutoMapper can also aggregate/flatten associated collections, but that's a different chapter.

Upvotes: 4

Related Questions