Jak użyć automapper do mapowania zestawu danych z wieloma tabelami

ZASTRZEŻENIE: jest to kopia wklejona ze starszego posta stosu stackoverflow, który nie jest już dostępny, ale mam ten sam problem, więc wydawało się właściwe ponowne przesłanie go, ponieważ nigdy nie odpowiedział.

Mam procedurę składowaną, która zwróci 4 zestawy wyników (kontakty, adresy, e-mail, telefony), które są wypełniane w zestawie danych. Chciałbym użyć AutoMappera do wypełnienia złożonego obiektu.

public class Contact 
{
    public Guid ContactId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Address> Addresses { get; set; }
    public List<Phone> Phones { get; set; }
    public List<Email> Emails { get; set; }
}

public partial class Address:BaseClass
{
    public Guid ContactId { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string Address3 { get; set; }
    public string City { get; set; }
    public string StateProvince { get; set; }
    public string PostalCode { get; set; }
    public string CountryCode { get; set; }   
}

public class Email
{
    public Guid EmailId { get; set; } 
    public Guid ContactId { get; set; } 
    public string EmailAddress { get; set; }
}

public class Phone
{
    public Guid PhoneId { get; set; } 
    public Guid ContactId { get; set; }         
    public string Number { get; set; } 
    public string Extension { get; set; }
}

Mam metodę, która otrzyma dane i zwróci listę kontaktów. Po wypełnieniu zestawu danych definiuję relacje między tabelami.

Znalazłem wiele przykładów, w których konwertujesz DataSet (lub tabelę) na czytnik za pomocą metody CreateDataReader i właśnie to robię tutaj. Metoda faktycznie przeanalizuje pierwszą tabelę w obiekcie, ale nie wyliczy jej w powiązanych tabelach.

public List<Contact> GetContacts()
{
    List<Contact> theList = null;

    // Get the data
    Database _db = DatabaseFactory.CreateDatabase();
    DataSet ds = db.ExecuteDataSet(CommandType.StoredProcedure, "GetContacts");

    //The dataset should contain 4 tables
    if (ds.Tables.Count == 4) 
    {    
        //Create the maps
        Mapper.CreateMap<IDataReader, Contact>(); // I think I'm missing something here
        Mapper.CreateMap<IDataReader, Address>();
        Mapper.CreateMap<IDataReader, Email>();
        Mapper.CreateMap<IDataReader, Phone>();

        //Define the relationships        
        ds.Relations.Add("ContactAddresses", ds.Tables[0].Columns["ContactId"], ds.Tables[1].Columns["ContactId"]);
        ds.Relations.Add("ContactEmails", ds.Tables[0].Columns["ContactId"], ds.Tables[2].Columns["ContactId"]);
        ds.Relations.Add("ContactPhones", ds.Tables[0].Columns["ContactId"], ds.Tables[3].Columns["ContactId"]);

        IDataReader dr = ds.CreateDataReader();
        theList = Mapper.Map<List<Contact>>(dr);    
    }

    return (theList);    
}

Czuję, że brakuje mi czegoś w mapowaniu obiektu kontaktu, ale nie mogę znaleźć dobrego przykładu do naśladowania.

Jeśli ręcznie zapełnię obiekt kontaktu, a następnie przekażę go do mojego kontrolera, poprawnie załaduje obiekt ContactModel przy użyciu bezpośredniego mapowania

public ActionResult Index()
{
    //From the ContactController
    Mapper.CreateMap<Contact, Models.ContactModel>();
    Mapper.CreateMap<Address, Models.AddressModel>();

    List<Models.ContactModel> theList = Mapper.Map<List<Contact>, List<Models.ContactModel>>(contacts);

    return View(theList);
}

Czy to, co chcę zrobić, jest możliwe?

questionAnswers(2)

yourAnswerToTheQuestion