ऑटोमैपर के साथ एक संपत्ति की मैपिंग पर ध्यान न दें


285

मैं ऑटोमैपर का उपयोग कर रहा हूं और मेरे पास निम्न परिदृश्य है: क्लास ऑर्डरमॉडल के पास 'ProductName' नामक एक संपत्ति है जो डेटाबेस में नहीं है। इसलिए जब मैं मानचित्रण करने की कोशिश करता हूं:

Mapper.CreateMap<OrderModel, Orders>(); 

यह एक अपवाद उत्पन्न करता है:

"Project.ViewModels.OrderModel पर निम्नलिखित 1 गुण मैप नहीं किए गए हैं: 'ProductName'

मैंने AutoMapper के Wiki पर अनुमानों के लिए पढ़ा है विपरीत मामले (अतिरिक्त विशेषता गंतव्य पर है, उस स्रोत में नहीं जो मेरे मामले में है)

मैं इस संपत्ति की मैपिंग करने के लिए ऑटोमैपर से कैसे बच सकता हूं?


7
Automapper उस तरह से काम नहीं करता है। यह केवल गंतव्य ऑब्जेक्ट पर गुणों के बारे में चिंतित है। Src में 100 अतिरिक्त गुण हो सकते हैं - आटोमैपर केवल भाग्य गुणों को मैप करता है। मैपिंग अपवाद के कारण कुछ और होना चाहिए। क्या आप कुछ कोड काम नहीं कर रहे हैं?
पैट्रिकसिटेले

यह वही करता है जो आप अपने आप से पूछते हैं। स्पष्ट करने के लिए कुछ कोड पोस्ट करें
BeRecursive

निम्नलिखित पदों पर एक नज़र है, ये आपकी मदद कर सकता है stackoverflow.com/questions/4456519/… stackoverflow.com/questions/4052579/…
Divi

3
@Patrick AutoMapper विधि / संपत्ति के नाम के विश्लेषण के साथ कुछ ट्रिक्स करता है। यह संभव है कि स्रोत पर एक संपत्ति है जिसे अनजाने में मैप किया जा रहा है, भले ही गंतव्य पर सटीक मिलान न हो। यही कारण है कि जब ऐसा होता है तो इसे रोकने के लिए एक ForSourceMember (... अनदेखा करें ())।
एरोनल्स

जवाबों:


477

जिमी बोगार्ड से: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());

यह उनके ब्लॉग की टिप्पणियों में से एक है


13
इसके अलावा, CreateMap<Foo, Bar>().ForSourceMember(x => x.Blarg, opt => opt.Ignore());उपयोगी हो सकता है
stackoverfloweth

5
@stackoverfloweth क्या आपका मतलब यह नहीं है CreateMap<SourceType, DestType> (MemberList.Source).ForSourceMember(x => x.MySourceProperty, opt => opt.DoNotValidate()):?
मोंटी

12
अनदेखे को ForSourceMember में DoNotValidate के साथ बदल दिया गया है: github.com/AutoMapper/AutoMapper/blob/master/docs/…
Jamie

@Jamie @monty - मैंने इसे फिर से अपडेट करना शुरू किया: आपकी टिप्पणी, लेकिन ऐसा लगता है कि वाक्यविन्यास परिवर्तन केवल प्रक्षेपण मामले को प्रभावित करता है (जहां स्रोत संपत्ति को नजरअंदाज करने की आवश्यकता है)। ओपी का अनुरोध गंतव्य संपत्ति की उपेक्षा करना है, इसलिए, Ignore()सही वाक्यविन्यास बना हुआ है। इसका कारण यह है कि इंटरफ़ेस Ignoreपर सिंटैक्स परिवर्तन किया गया था, ISourceMemberConfigurationExpressionलेकिन असंतुष्ट IMemberConfigurationExpression`3इंटरफ़ेस पर नहीं ।
स्मार्टकेमैन

2
@Franva ForMember () वास्तव में "ForDestinationMember ()" है
rvanlord

243

मैं शायद एक पूर्णतावादी का एक सा हूँ; मुझे वास्तव में ForMember (..., x => x.Ignore ()) सिंटैक्स पसंद नहीं है। यह एक छोटी सी बात है, लेकिन यह मेरे लिए मायने रखती है। मैंने इसे थोड़ा अच्छा बनाने के लिए यह विस्तार विधि लिखी है:

public static IMappingExpression<TSource, TDestination> Ignore<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> map,
    Expression<Func<TDestination, object>> selector)
{
    map.ForMember(selector, config => config.Ignore());
    return map;
}

यह इस तरह से इस्तेमाल किया जा सकता है:

Mapper.CreateMap<JsonRecord, DatabaseRecord>()
        .Ignore(record => record.Field)
        .Ignore(record => record.AnotherField)
        .Ignore(record => record.Etc);

आप इसके साथ काम करने के लिए इसे फिर से लिख सकते हैं params, लेकिन मुझे लैंबडास के भार के साथ एक विधि पसंद नहीं है।


6
मुझे पता है कि यह प्रारंभिक प्रश्न से परे है, लेकिन मुझे वास्तव में यह उत्तर पसंद है, इसकी स्वच्छ, पढ़ने में बहुत आसान और तुरंत पुन: उपयोग करने के लिए प्लस को समझना आसान है
Lski

के बारे में params: आप एक एकल लैम्ब्डा के अंदर से चयनकर्ताओं की एक सरणी वापस कर सकते हैं, फिर प्रत्येक चयनकर्ता के साथ मैप करें foreachया Select()शायद कम गन्दा दिखने वाला नहीं है, हालांकि।
jpaugh

धन्यवाद @Steve Rukuts, जो कोई भी विस्तार विधि की तलाश कर रहा है, वह स्रोत सदस्यों की उपेक्षा करने के लिए आप इस सार्वजनिक स्थैतिक IMappingExpression <TSource, TDestination> IgnoreSourceValidation का उपयोग कर सकते हैं <TSource, TDestination> (यह IMappingExpression <TSource, TDestination> नक्शा, अभिव्यक्ति <TSource , वस्तु >> चयनकर्ता) {map.ForSourceMember (चयनकर्ता, कॉन्फ़िगरेशन => config.DoNotValidate ()); वापसी का नक्शा; }
जेसन डायस

79

तुम यह केर सकते हो:

conf.CreateMap<SourceType, DestinationType>()
   .ForSourceMember(x => x.SourceProperty, y => y.Ignore());

क्या ऑटोमैपर के पास ForSourceMember एक्सटेंशन है?
Redeemed1

मैं वर्तमान में ऐसा करता हूं, लेकिन यह आदर्श होगा कि इन सभी को अनदेखा न करें ...:
टॉम स्टिकेल

क्या आपको पता है कि मैपिंग करते समय वास्तव में मैपिंग करते समय अनदेखा करने का कोई तरीका है या नहीं?
सैम मैं कह रहा हूं कि


3
प्रश्न में दिए गए परिदृश्य के लिए, यह स्वीकृत उत्तर होना चाहिए। वर्तमान स्वीकृत उत्तर गंतव्य ऑब्जेक्ट में गुणों की मैपिंग की उपेक्षा करता है। यह सवाल सोर्स ऑब्जेक्ट में मैपिंग को नजरअंदाज करने के बारे में पूछ रहा है।
रॉब एस।

28

बस स्वचालित रूप से ऐसा करने की कोशिश करने वाले किसी भी व्यक्ति के लिए, आप गंतव्य स्थान पर गैर-मौजूदा गुणों को अनदेखा करने के लिए उस विस्तार विधि का उपयोग कर सकते हैं:

public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof(TSource);
    var destinationType = typeof(TDestination);
    var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType)
        && x.DestinationType.Equals(destinationType));
    foreach (var property in existingMaps.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

पालन ​​के रूप में इस्तेमाल किया जा करने के लिए:

Mapper.CreateMap<SourceType, DestinationType>().IgnoreAllNonExisting();

टिप के लिए कैन गेनर को धन्यवाद :)

स्रोत: http://cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/



1
IMapper को इंजेक्ट करते समय यह काम नहीं करता है। AutoMapper के नवीनतम संस्करण में Mapper.GetAllTypeMaps मौजूद नहीं है। इसके अतिरिक्त, जब मैं अपने मैप्स को एक AutoMapper.Profile में सेट करता हूं और फिर बाद में IMapper को इंजेक्ट करता हूं, तो मुझे यह अपवाद मिला "मैपर इनिशियलाइज़्ड नहीं। कॉल को उपयुक्त कॉन्फ़िगरेशन के साथ प्रारंभ करें। यदि आप किसी कंटेनर या अन्य माध्यम से मैपर इंस्टेंस का उपयोग करने का प्रयास कर रहे हैं, तो सुनिश्चित करें कि आप। स्थिर Mapper.Map विधियों के लिए कोई कॉल नहीं है, और यदि आप ProjectTo या UseAsDataSource एक्सटेंशन विधियों का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप उपयुक्त IConfigurationProvider उदाहरण में पास करते हैं। "
रिस्तोगोड

मैं अभी मिलता हूं 'Mapper' does not contain a definition for 'GetAllTypeMaps' [DSSTools]..
बस्सी

2
@ बासी उपयोग Mapper.Configuration.GetAllTypeMaps() स्रोत
माइक बुवनलैंडर

28

अब (AutoMapper 2.0) एक IgnoreMapविशेषता है, जिसे मैं धाराप्रवाह सिंटैक्स के बजाय उपयोग करने जा रहा हूं जो कि थोड़ा भारी IMHO है।


35
अनदेखी विशेषता हालांकि आपके आवेदन के माध्यम से ऑटो-मैपर लीक करती है।
फिल

11
AutoMapper एक ऐसी चीज है, जिसका मैं सभी जगह लीक होने का कोई मतलब नहीं है। ;)
पावेल क्राकोविएक

4
आप हमेशा व्युत्पन्न विचार कर सकते हैं IgnoreMapAttribute
अलापागो

1
यह एक आधार संपत्ति को अनदेखा करने का एक अच्छा तरीका है जो कई वस्तुओं में विरासत में मिला है। हर मैपिंग कॉन्फिग में इसे इग्नोर करने से बचाता है।
चेस फ्लोरल

23

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

Mapper.CreateMap<OrderModel, Orders>(MemberList.Source); 

अब मेरा मानचित्रण सत्यापन विफल हो जाता है, दूसरे की आवश्यकता होती है Ignore(), हर बार जब मैं अपने डोमेन वर्ग में एक संपत्ति जोड़ता हूं।


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

5
यह उत्तर बच्चों का है, कि आधिकारिक इतना newbies भ्रमित नहीं होगा
Piotr M

0

जिस संपत्ति को नजरअंदाज करने की जरूरत है, उस पर इग्नोरएट्रिब्यूट का इस्तेमाल कर सकते हैं


2
इसका [IgnoreMap]सेIgnoreMapAttribute
fiorebat

-5

हैलो सभी कृपया इसका उपयोग करें यह ठीक काम कर रहा है ... ऑटो मैपर के लिए C में कई .ForMember का उपयोग करें

        if (promotionCode.Any())
        {
            Mapper.Reset();
            Mapper.CreateMap<PromotionCode, PromotionCodeEntity>().ForMember(d => d.serverTime, o => o.MapFrom(s => s.promotionCodeId == null ? "date" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", DateTime.UtcNow.AddHours(7.0))))
                .ForMember(d => d.day, p => p.MapFrom(s => s.code != "" ? LeftTime(Convert.ToInt32(s.quantity), Convert.ToString(s.expiryDate), Convert.ToString(DateTime.UtcNow.AddHours(7.0))) : "Day"))
                .ForMember(d => d.subCategoryname, o => o.MapFrom(s => s.subCategoryId == 0 ? "" : Convert.ToString(subCategory.Where(z => z.subCategoryId.Equals(s.subCategoryId)).FirstOrDefault().subCategoryName)))
                .ForMember(d => d.optionalCategoryName, o => o.MapFrom(s => s.optCategoryId == 0 ? "" : Convert.ToString(optionalCategory.Where(z => z.optCategoryId.Equals(s.optCategoryId)).FirstOrDefault().optCategoryName)))
                .ForMember(d => d.logoImg, o => o.MapFrom(s => s.vendorId == 0 ? "" : Convert.ToString(vendorImg.Where(z => z.vendorId.Equals(s.vendorId)).FirstOrDefault().logoImg)))
                .ForMember(d => d.expiryDate, o => o.MapFrom(s => s.expiryDate == null ? "" : String.Format("{0:dd/MM/yyyy h:mm:ss tt}", s.expiryDate))); 
            var userPromotionModel = Mapper.Map<List<PromotionCode>, List<PromotionCodeEntity>>(promotionCode);
            return userPromotionModel;
        }
        return null;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.