2012-05-22 12 views
8

क्या ऑटोमैपर अस्थायी रूप से विशेष मैपिंग को निलंबित करने के लिए "राजी" हो सकता है?क्या ऑटोमैपर अस्थायी रूप से विशेष मैपिंग को निलंबित करने के लिए "राजी" हो सकता है?

यह समझाने के लिए कि क्या पूरा करने की कोशिश कर रहा हूं, मैं एक उदाहरण का उपयोग करूंगा। मान लीजिए कि मेरे पास एक भंडार है, छात्र रिपोजिटरी, जो कि डेटाबेस, पाठ्यक्रम, क्रियाकलाप, क्लब इत्यादि जैसे डेटाबेस ऑब्जेक्ट्स (तालिकाओं) के साथ इंटरैक्ट करने के लिए LINQ का उपयोग करता है। आवेदन पक्ष पर छात्र डोमेन, छात्र, गतिविधि, क्लब मिलान कर रहे हैं। छात्र वर्ग की तरह प्रकार कोर्स, गतिविधि की सरणी के सदस्यों, और क्लब में शामिल हैं:

public class Student 
{ 
    // ... more members 
    public Course[] Courses { get; set; } 
    public Activity[] Activities { get; set; } 
    public Club[] Clubs { get; set; } 
    // ... even more members 
} 

AutoMapper डोमेन वस्तुओं के लिए जहां मैपिंग की तरह StudentRepository की एक स्थिर निर्माता में परिभाषित कर रहे हैं करने के लिए डेटाबेस ऑब्जेक्ट्स मैप करने के लिए कॉन्फ़िगर किया गया है:

public class StudentRepository : IStudentRepository 
{ 
    static class StudentRepository 
    { 
     // ... other mappings 

     Mapper.CreateMap<TableStudent, Student>() 
      .ForMember(dest => dest.Courses, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Course>>(src.TableCourses))) 
      .ForMember(dest => dest.Activities, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Activity>>(src.TableActivities))) 
      .ForMember(dest => dest.Clubs, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Clubs>>(src.TableClubs))) 
     // where TableStudents, TableCourses, TableActivities, TableClubs are database entities 

     // ... yet more mappings 

    } 
} 

क्या एक फ़ंक्शन ब्लॉक में मैपिंग को निलंबित करने के लिए ऑटोमैपर को "मनाने" संभव है?

public Student[] GetStudents() 
{ 
    DataContext dbContext = new StudentDBContext(); 

    var query = dbContext.Students; 
    // => SUSPEND CONFIGURATION MAPPINGS for Subjects, Activities and Clubs WHILE STILL making use of others 
    // => The idea here it to take personal charge of 'manually' setting the particular members (*for some specific reasons) 

    var students = Mapper.Map<Student>(query); // => Still be able to use AutoMapper to map other members 
} 

public Student[] OtherStudentRepositoryMethods() 
{ 
    // Other repository methods continue to make use of the mappings configured in the static constructor 
} 

नोट "कुछ विशेष कारणों के लिए ": एक कारण यह एक नियंत्रण AutoMapper से दूर ले करने के लिए इस http://codebetter.com/davidhayden/2007/08/06/linq-to-sql-query-tuning-appears-to-break-down-in-more-advanced-scenarios/ जहां एक 1 के मामले में होगा चाहते हो सकता है: उदाहरण के लिए n संघों, LINQ एसक्यूएल के लिए केवल एक 1: एन एसोसिएशन प्रति क्वेरी में शामिल होने का समर्थन करता है। ऑटोमैपर यहां अक्षम होगा - एन छात्रों को एन छात्रों के लिए पाठ्यक्रम लोड करने के लिए एन कॉल करने के लिए, एन एन कॉल करने के लिए एन कॉल करने के लिए एन एन कॉल वापस लौटे, और संभवतः एन एन छात्रों के लिए क्लब लोड करने के लिए एन और कॉल वापस लौटे।

+0

मैंने यह कोशिश नहीं की है, लेकिन 'प्रीमैप' मैपर है। क्रेटमैप <टेबलस्ट्यूडेंट, छात्र>()। मैपमैप (एक्स => {मैपर.क्रेटमैप <टेबलस्ट्यूडेंट, छात्र>()। ForMember ...}) पहले मानचित्र में नक्शा बनाएं। नक्शा कई बार फिर से बनाने के लिए अतिरिक्त चेक हो सकते हैं। –

उत्तर

4

क्या एक फ़ंक्शन ब्लॉक में मैपिंग को निलंबित करने के लिए ऑटोमैपर को "मनाने" संभव है?

मुझे पता है के रूप में, सबसे अच्छा तरीका यह करने के लिए - उपयोग इस

public class StudentRepository : IStudentRepository 
{ 
    static class StudentRepository 
    { 
     // ... other mappings 

     Mapper.CreateMap<TableStudent, Student>() 
      .ForMember(dest => dest.Courses, opt => opt.Ignore()) 
      .ForMember(dest => dest.Activities, opt => opt.Ignore()) 
      .ForMember(dest => dest.Clubs, opt => opt.Ignore()) 
     // where TableStudents, TableCourses, TableActivities, TableClubs are database entities 

     // ... yet more mappings 

    } 
} 

भी तरह ध्यान न दें(), के रूप में यह पहले देखा गया था, मैं प्रत्येक लक्ष्य के लिए अलग प्रोफ़ाइल का उपयोग करने के लिए आपको सलाह देते हैं आप हासिल करना चाहते हैं। यहां एक उदाहरण है

public BaseService() 
{ 
    AutoMapperRegistry.Configure(); 
} 

public class AutoMapperRegistry 
{ 
    public static void Configure() 
    { 
     Mapper.Initialize(x => 
     { 
      x.AddProfile<ServiceProfile1>(); 
      x.AddProfile<ServiceProfileReverseProfile1>(); 
     }); 
    } 
} 

public class ServiceProfile1 : Profile 
{ 
    protected override string ProfileName 
    { 
     get 
     { 
      return "ServiceProfile1"; 
     } 
    } 

    protected override void Configure() 
    { 
     Mapper.CreateMap<DataContract_Sub, DTO_Sub>(); 
     Mapper.CreateMap<DataContract, DTO>() 
      .ForMember(x => x.DataContract_Sub, opt => opt.MapFrom(y => y.DTO_Sub)) 
    .BeforeMap((s, d) => 
      { 
       // your custom logic 
      }) 
    .AfterMap((s, d) => 
      { 
       // your custom logic 
      }); 
    } 
} 
+0

यह एक कामकाज की तरह प्रतीत होता है। पचाने ... –

2

यह प्राप्त करने का एक तरीका प्रत्येक परिदृश्य के लिए अलग मैपिंग इंजन उदाहरण बनाना होगा, जिस तरह से आप अलग-अलग मानचित्रों को कॉन्फ़िगर कर सकते हैं, जैसा कि जिमी बोगर्ड से this answer में सुझाया गया है, एक ही प्रकार को विभिन्न तरीकों से मैप करना चाहते हैं।

0

हम्म ... प्रतिक्रिया के लिए धन्यवाद दोस्तों। मैंने सभी उत्तरों और सुझावों पर विचार करने में समय लगाया। कोई भी विशेष रूप से अच्छी तरह से प्रस्तुत नहीं करता है हालांकि उन्होंने विचार के लिए बहुत सारे भोजन प्रदान किए हैं। मैंने सोचा कि मुझे कुछ कोशिश करनी चाहिए जो मैंने कोशिश की थी। (अस्वीकरण: मेरी राय यह है कि यह एक गंदा दृष्टिकोण है - कई चीजें गलत हो सकती हैं - और मर्फी के कानूनों को जारी रखना जारी है)। मैपिंग को "निलंबित" करने के लिए आप विशेष उदाहरण में अनदेखी कार्यक्षमता का लाभ उठा सकते हैं। आमतौर पर, एक ट्राई एवं कैच ब्लॉक के रूप में इस प्रकार है:

public Student[] GetStudents() 
{ 
    try 
    { // Suspend/Ignore the mappings 
     // => SUSPEND CONFIGURATION MAPPINGS for Subjects, Activities and Clubs 
     Mapper.CreateMap<TableStudent, Student>() 
        .ForMember(dest => dest.Courses, opt => opt.Ignore()) 
        .ForMember(dest => dest.Activities, opt => opt.Ignore()) 
        .ForMember(dest => dest.Clubs, opt => opt.Ignore()) 

     DataContext dbContext = new StudentDBContext(); 

     var query = dbContext.Students; 

     // other logic ... 

     var students = Mapper.Map<Student>(query); // => Still be able to use AutoMapper to map other members 
     // set the properties you needed to do manually 
    } 
    finally // Restore back the mappings 
    { 
     Mapper.CreateMap<TableStudent, Student>() 
        .ForMember(dest => dest.Courses, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Course>>(src.TableCourses))) 
        .ForMember(dest => dest.Activities, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Activity>>(src.TableActivities))) 
        .ForMember(dest => dest.Clubs, opt => opt.MapFrom(src => Mapper.Map<IEnumerable<Clubs>>(src.TableClubs))) 
    } 
} 

जैसे कि मैंने उल्लेख किया है, इसकी शायद गंदे। कोड की तरह मैं खुश नहीं रहूंगा - खासकर जब से मुझे नहीं पता कि CreateMap() अंततः ब्लॉक में विफल होने पर किस प्रकार की असाधारण स्थितियां उत्पन्न हो सकती हैं, लेकिन एक विरासत एप्लिकेशन पर जहां आप दृष्टिकोण को ओवरहाल नहीं कर सकते संभावित रूप से उपरोक्त @AndriyZakharko द्वारा सुझाए गए विभिन्न प्रोफाइल का उपयोग करें, आप अस्थायी रूप से नियंत्रण प्राप्त करने के लिए इसका उपयोग कर सकते हैं। मैंने इसे व्यक्तिगत रूप से आजमाया।

संबंधित मुद्दे