2012-09-04 16 views
6

AutoMapper मानचित्रण को कैसे कॉन्फ़िगर करें जब मैं UseDestinationValue विधि से व्यवहार का उपयोग करना चाहते हैं, लेकिन केवल जब गंतव्य संपत्ति null नहीं है।UseDestinationValue केवल जब गंतव्य संपत्ति रिक्त नहीं है

कुछ इस तरह:

Mapper.CreateMap<Item, ItemViewModel>() 
    .ForMember(x => x.Details, _ => _.UseDestinationValue(dontUseWhenNullDestination: true)) 

संपादित करें उपयोग के

class ItemDetails { 
    public string Info { get; set; } 
    public string ImportantData { get; set; } // only in Domain, not in ViewModel 
} 

class Item { 
    public ItemDetails Details { get; set; } 
} 

class ItemDetailsViewModel { 
    public string Info { get; set; } 
} 

class ItemViewModel { 
    public ItemDetailsViewModel Details { get; set; } 
} 

अब उदाहरण। मेरे पास ItemViewModel कक्षा है और मैं इसे Item कक्षा में मैप करना चाहता हूं।

मानचित्रण विन्यास:

Mapper.CreateMap<Item, ItemViewModel>() 
     .ForMember(x => x.Details, _ => _.UseDestinationValue()) 
  1. पहला मामला - गंतव्य संपत्ति Item.Details संपत्ति शून्य नहीं है। अब मैं संपत्ति के इस गंतव्य उदाहरण का उपयोग करने के लिए ऑटोमैपर का उपयोग करने के लिए चाहता हूं, क्योंकि यह शून्य नहीं है। ,

    var item = new Item { 
        Details = new Details { 
         Info = "Old text", 
         ImportantData = "Data" 
        } 
    }; 
    
    var itemViewModel = new ItemViewModel { 
        Details = new DetailsViewModel { 
         Info = "New text" 
        } 
    };  
    
    Mapper.Map(itemViewModel, item); 
    

    AutoMapper क्योंकि UseDestinationValue की मौजूदगी की, item.Details उदाहरण छोड़ने के लिए और केवल item.Details.Info गुण सेट होगा:

    और तर्क इस तरह दिखता है।

  2. दूसरा मामला - गंतव्य संपत्ति Item.Details संपत्ति न्यूल है। अब मैं ऑटोमैपर चाहता हूं कि इस शून्य उदाहरण का उपयोग न करें, लेकिन नया बनाएं। प्रश्न यह है कि इस मामले को ध्यान में रखकर मैपिंग को कैसे कॉन्फ़िगर किया जाए?

    var item = new Item { 
        Details = null 
    }; 
    
    var itemViewModel = new ItemViewModel { 
        Details = new DetailsViewModel { 
         Info = "New text" 
        } 
    }; 
    
    Mapper.Map(itemViewModel, item); 
    

    समस्या

    यहाँ मैं एक समस्या है, क्योंकि मानचित्रण के बाद, item.Details संपत्ति (UseDestinationValue के उपयोग, जिसमें null है की वजह से रिक्त हो जाएगा:

    तर्क इस तरह दिखता है ये मामला)।

कारण

NHibernate, डेटाबेस से इकाई प्राप्त करने के बाद, यह एक प्रॉक्सी में डालता है। तो Details लोड किए गए ऑब्जेक्ट की प्रॉपर्टी एक प्रकार का नहीं है: ItemDetails, लेकिन ItemDetailsNHibernateProxy - इसलिए मुझे इस प्रकार का उपयोग करना होगा, जब मैं इस मौजूदा ऑब्जेक्ट को बाद में डेटाबेस में सहेजना चाहता हूं। लेकिन अगर यह संपत्ति null है, तो मैं एक शून्य गंतव्य मान का उपयोग नहीं कर सकता, इसलिए ऑटोमैपर को एक नया उदाहरण बनाना चाहिए।

धन्यवाद, क्रिस

+0

तो तुम UseDestinationValue के अलावा कुछ करना चाहते हैं

मैं करने के लिए इसी कोड के साथ समाप्त हो गया अगर यह शून्य है? – PatrickSteele

+0

हां, जब मैं गंतव्य संपत्ति नल करता हूं तो मैं कुछ और करना चाहता हूं। – cryss

+0

क्या आप कुछ कामकाजी नमूना कोड प्रदान कर सकते हैं जो आपको दिखा रहा है कि आप चीजों को मैप किए हुए चीजों को कैसे बना सकते हैं। वर्तमान में Auotmapper क्या करता है। मैं जो भी पूछ रहा हूं उसे प्राप्त नहीं कर रहा हूं। – PatrickSteele

उत्तर

0

मुझे लगता है कि NullSubstitute विकल्प आपके लिए काम करेगा।देखें: http://weblogs.asp.net/psteele/archive/2011/03/18/automapper-handling-null-members.aspx

संपादित करें आप की तरह विवरण के लिए अपने मानचित्रण के लिए एक छोटे से सशर्त तर्क जोड़ने के लिए आवश्यकता हो सकती है

लग रहा है (और UseDestinationValue विकल्प को छोड़):

.ForMember(d => d.Details, 
    o => o.MapFrom(s => s.Details == null ? new ItemDetails() : Mapper.Map<ItemDetailsViewModel, ItemDetails>(s.Details)) 
+1

स्रोत मूल्य शून्य होने पर NullSubstitute उपयोगी है। – cryss

0

मैं इस एक ही समस्या थी NHibernate इकाइयों से निपटने और मुझे इसके लिए काफी सरल समाधान मिला।

आपको ItemViewModel कन्स्ट्रक्टर में विवरण प्रॉपर्टी प्रारंभ करना चाहिए। इस तरह गंतव्य मूल्य शून्य नहीं है। बेशक यह अधिक जटिल मामलों (जैसे सार वर्गों) में काम नहीं करता है।

1

यह वही समस्या थी, लेकिन ईएफ के साथ। पहले मैप का उपयोग करने के बारे में क्राइस की टिप्पणी ने मुझे सही दिशा में इंगित किया।

कॉन्फ़िगर में() विधि:

Mapper.CreateMap<ItemViewModel, Item>() 
      .AfterMap((s, d) => { MapDetailsAction(s, d); }) 
      .ForMember(dest => dest.Details, opt => opt.UseDestinationValue()); 

तो कार्रवाई:

Action<ItemViewModel, Item> MapDetailsAction = (source, destination) => 
     { 
      if (destination.Details == null) 
      { 
       destination.Details = new Details(); 
       destination.Details = 
        Mapper.Map<ItemViewModel, Item>(
        source.Details, destination.Details); 
      } 
     };