DISCLAIMER: jest to wklej do kopiowania ze starszego postu stackoverflow, który nie jest już dostępny, ale mam exaclty ten sam problem, więc wydawało się właściwe, aby go odświeżyć ponieważ nigdy nie otrzymał odpowiedzi.Jak korzystać z automappera do mapowania zbioru danych z wieloma tabelami
Mam procedura składowana, która zwróci 4 zestawy wyników (kontakty, adresy, e-mail, telefony), które są wypełnione 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 pobiera dane i zwraca listę kontaktów. Po zapełnieniu DataSet definiuję relacje między tabelami.
Znalazłem wiele przykładów, w których konwertujesz zestaw danych (lub tabelę) do czytnika za pomocą metody CreateDataReader i to właśnie tutaj robię. Metoda będzie w rzeczywistości analizować pierwszą tabelę w obiekcie, ale nie będzie ona wyliczana za pośrednictwem powiązanych tabel.
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);
}
Mam wrażenie, że brakuje mi czegoś w odwzorowaniu obiektu Kontakt, ale po prostu nie mogę znaleźć dobrego przykładu do naśladowania.
Gdybym ręcznie wypełniają obiekt kontaktowy, a następnie przekazać to do mojego kontrolera, to właściwie załadować obiekt ContactModel pomocą 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ę robić w ogóle możliwe?
Obawiałem się, że to będzie odpowiedź, dziękuję za przykład! –