2013-05-28 7 views
6

अस्वीकरण के साथ डेटासेट को मैप करने के लिए ऑटोमैपर का उपयोग कैसे करूं: यह एक पुराने स्टैक ओवरफ्लो पोस्ट से एक कॉपी पेस्ट है जो अब उपलब्ध नहीं है, लेकिन मेरे पास एक ही समस्या है, इसलिए इसे दोबारा पोस्ट करना उचित लगता है क्योंकि इसका कभी जवाब नहीं दिया गया था।मैं एकाधिक टेबल

मेरे पास एक संग्रहीत प्रक्रिया है जो 4 परिणाम सेट (संपर्क, पते, ईमेल, फोन) लौटाएगी जो डेटासेट में आबादी में आती है। मैं एक जटिल वस्तु को पॉप्युलेट करने के लिए ऑटोमैपर का उपयोग करना चाहता हूं।

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; } 
} 

मेरे पास एक तरीका है जो डेटा प्राप्त करेगा और संपर्क की एक सूची वापस कर देगा। डेटासेट पॉप्युलेट होने के बाद, मैं तालिकाओं के बीच संबंधों को परिभाषित करता हूं।

मुझे कई उदाहरण मिले हैं जहां आप DataSet (या तालिका) को CreateDataReader विधि का उपयोग करके एक पाठक में कनवर्ट करते हैं और यही वह है जो मैं यहां कर रहा हूं। विधि वास्तव में वस्तु में पहली तालिका को पार्स करेगा, लेकिन संबंधित तालिकाओं के माध्यम से गणना नहीं करेगा।

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);  
} 

मुझे लगता है कि मुझे संपर्क ऑब्जेक्ट के लिए मैपिंग में कुछ याद आ रहा है, लेकिन मुझे बस पालन करने के लिए एक अच्छा उदाहरण नहीं मिल रहा है।

मैं मैन्युअल रूप से संपर्क वस्तु को पॉप्युलेट और फिर पारित मेरी नियंत्रक करने के लिए है, तो यह ठीक से ContactModel वस्तु एक सीधा मानचित्रण

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); 
} 

का उपयोग कर क्या मैं भी संभव करना चाहता हूँ लोड होगा?

उत्तर

9

आईडीटाइडर मैपर बहुत आसान है, यह किसी ऑब्जेक्ट को डेटा रीडर से पॉप्युलेट कर सकता है, जहां यह कॉलम नामों से ऑब्जेक्ट गुणों को मानचित्र करता है। इसे संबंधों के साथ जटिल डेटा संरचनाएं बनाने के लिए डिज़ाइन नहीं किया गया था, आदि

साथ ही, डेटासेट.क्रेटडेटा रीडर एक एकाधिक परिणाम डेटा रीडर उत्पन्न करेगा - यानी पाठक के पास प्रत्येक तालिका के लिए कुछ परिणाम सेट होंगे, लेकिन यह संरक्षित नहीं होगा संबंध

तो, आप जो चाहते हैं उसे प्राप्त करने के लिए, आपको प्रत्येक तालिका के लिए पाठक बनाने, प्रत्येक पाठक को विभिन्न संग्रह में मैप करने की आवश्यकता है, और फिर अंतिम जटिल ऑब्जेक्ट बनाने के लिए इन परिणामों का उपयोग करें।

यहां मैं सरल दृष्टिकोण प्रदान कर रहा हूं, लेकिन आप जंगली जा सकते हैं, और create custom resolvers, आदि, सबकुछ को समाहित करने के लिए।

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using AutoMapper; 
using NUnit.Framework; 

namespace StackOverflowExample.Automapper 
{ 
    public class Contact 
    { 
     public Guid ContactId { get; set; } 
     public string Name { get; set; } 
     public List<Address> Addresses { get; set; } 
    } 

    public partial class Address 
    { 
     public Guid AddressId { get; set; } 
     public Guid ContactId { get; set; } 
     public string StreetAddress { get; set; } 
    } 

    [TestFixture] 
    public class DatasetRelations 
    { 
     [Test] 
     public void RelationMappingTest() 
     { 
      //arrange 
      var firstContactGuid = Guid.NewGuid(); 
      var secondContactGuid = Guid.NewGuid(); 

      var addressTable = new DataTable("Addresses"); 
      addressTable.Columns.Add("AddressId"); 
      addressTable.Columns.Add("ContactId"); 
      addressTable.Columns.Add("StreetAddress"); 
      addressTable.Rows.Add(Guid.NewGuid(), firstContactGuid, "c1 a1"); 
      addressTable.Rows.Add(Guid.NewGuid(), firstContactGuid, "c1 a2"); 
      addressTable.Rows.Add(Guid.NewGuid(), secondContactGuid, "c2 a1"); 

      var contactTable = new DataTable("Contacts"); 
      contactTable.Columns.Add("ContactId"); 
      contactTable.Columns.Add("Name"); 
      contactTable.Rows.Add(firstContactGuid, "contact1"); 
      contactTable.Rows.Add(secondContactGuid, "contact2"); 

      var dataSet = new DataSet(); 
      dataSet.Tables.Add(contactTable); 
      dataSet.Tables.Add(addressTable); 

      Mapper.CreateMap<IDataReader, Address>(); 
      Mapper.CreateMap<IDataReader, Contact>().ForMember(c=>c.Addresses, opt=>opt.Ignore()); 

      //act 
      var addresses = GetDataFromDataTable<Address>(dataSet, "Addresses"); 
      var contacts = GetDataFromDataTable<Contact>(dataSet, "Contacts"); 
      foreach (var contact in contacts) 
      { 
       contact.Addresses = addresses.Where(a => a.ContactId == contact.ContactId).ToList(); 
      } 
     } 

     private IList<T> GetDataFromDataTable<T>(DataSet dataSet, string tableName) 
     { 
      var table = dataSet.Tables[tableName]; 
      using (var reader = dataSet.CreateDataReader(table)) 
      { 
       return Mapper.Map<IList<T>>(reader).ToList(); 
      } 
     } 
    } 
} 
+1

मुझे डर था कि यह जवाब होगा, उदाहरण के लिए धन्यवाद! –

0

मैं पार्टी के लिए अविश्वसनीय रूप से देर से हूं, लेकिन अगर यह किसी और की मदद करता है।

मैंने जो किया वह Json.NET का उपयोग कर एक JSON स्ट्रिंग पर मेरे डेटासेट को क्रमबद्ध कर रहा था।

var datasetSerialized = JsonConvert.SerializeObject(dataset, Formatting.Indented); 

देखें दृश्य स्टूडियो में रहते हुए डिबगिंग स्ट्रिंग के रूप json और अपने क्लिपबोर्ड को यह कॉपी।

फिर दृश्य स्टूडियो में संपादित करने के लिए जाना -> चिपकाने के विकल्प -> चिपकाएं JSON क्लासेस

के रूप में इसके बाद आप रिश्तों के साथ प्रत्येक तालिका के लिए एक POCO होगा।

अंत में, जेएसओएन कक्षाओं को चिपकाते समय अपने JSON को "रूट ऑब्जेक्ट" में बेकार करें।

var rootObj = JsonConvert.DeserializeObject<RootObject>(datasetSerialized); 
संबंधित मुद्दे