Automapper ile bir özelliği eşleştirmeyi yoksay


285

Automapper kullanıyorum ve aşağıdaki senaryo var: Class OrderModel veritabanında olmayan 'ProductName' adlı bir özelliğe sahiptir. Bu yüzden eşleştirmeyi yapmaya çalıştığımda:

Mapper.CreateMap<OrderModel, Orders>(); 

Bir istisna oluşturur:

"Project.ViewModels.OrderModel üzerindeki şu 1 özellik eşlenmiyor: 'ProductName'

AutoMapper'ın Projeler için Wiki'sinde tam tersini okudum (ekstra özellik aslında benim durumum olan kaynakta değil, hedefte)

Bu özelliğin eşlemesini yapmak için otomatik haritayı nasıl önleyebilirim?


7
Automapper bu şekilde çalışmaz. Sadece hedef nesnedeki özellikler ile ilgilidir. Src 100 ekstra özellik içerebilir - Automapper yalnızca dest özelliklerini eşler. Eşleme istisnasına neden olan başka bir şey olmalı. İşe yaramayanların bazı kodlarını gönderebilir misiniz?
PatrickSteele

İstediğinizi otomatik olarak yapar.
Açıklığa


3
@Patrick AutoMapper, yöntem / özellik adlarını analiz etmek için bazı püf noktaları yapar. Kaynakta, hedefte tam bir eşleşme olmasa bile istemeden eşlenen bir özellik olması mümkündür. Bu nedenle, bunu önlemek için bir ForSourceMember (... Yoksay ()) vardır.
AaronLS

Yanıtlar:


478

Jimmy Bogard'dan: CreateMap<Foo, Bar>().ForMember(x => x.Blarg, opt => opt.Ignore());

Blogundaki yorumlardan birinde .


13
Ayrıca, CreateMap<Foo, Bar>().ForSourceMember(x => x.Blarg, opt => opt.Ignore());yararlı olabilir
stackoverfloweth

5
Şunu mu demek istedin CreateMap<SourceType, DestType> (MemberList.Source).ForSourceMember(x => x.MySourceProperty, opt => opt.DoNotValidate())?
monty

12
Yoksay, ForSourceMember'de DoNotValidate ile değiştirildi: github.com/AutoMapper/AutoMapper/blob/master/docs/…
Jamie

@Jamie @monty - Bunu yeniden güncellemeye başladım: yorumunuz, ancak sözdizimi değişikliği yalnızca projeksiyon durumunu etkiliyor gibi görünüyor (source özelliğinin yok sayılması gerektiği). OP'nin isteği bir hedef özelliği yok saymaktır, bu nedenle Ignore()doğru sözdizimi kalır. Sözdizimi değişikliği Bunun nedeni Ignoreüzerinde yapıldı ISourceMemberConfigurationExpressionancak ayrık üzerinde arayüzüne IMemberConfigurationExpression`3arayüzüne.
smartcaveman

2
@Franva ForMember () aslında "ForDestinationMember ()" dir
rvnlord

243

Belki biraz mükemmeliyetçiyim; ForMember (..., x => x.Ignore ()) sözdizimini gerçekten sevmiyorum. Bu küçük bir şey, ama benim için önemli. Biraz daha güzel yapmak için bu uzatma yöntemini yazdım:

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

Şu şekilde kullanılabilir:

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

Ayrıca çalışmak için yeniden yazabilirsiniz params, ancak lambdas yükleri ile bir yöntemin görünümünü sevmiyorum.


6
Bunun ilk sorunun ötesine geçtiğini biliyorum, ama bu cevabı gerçekten çok beğendim, temiz, okunması çok kolay ve anında anlaması artı yeniden kullanımı kolay
Lski

İlgili params: Bir dizi seçiciyi tek bir lambda içinden döndürebilir, daha sonra her bir seçicinin üzerine belki de daha az dağınık görünümlü foreachveya Select()daha az dağınık görünmeyebilirsiniz.
jpaugh

teşekkürler @Steve Rukuts, kaynak üyeleri yoksaymak için uzatma yöntemi arayan herkes için bu genel statik IMappingExpression <TSource, TDestination> IgnoreSourceValidation <TSource, TDestination> (bu IMappingExpression <TSource, TDestination> harita, İfade <Func <TSource , object >> selector) {map.ForSourceMember (seçici, config => config.DoNotValidate ()); dönüş haritası; }
Jason Dias

79

Bunu yapabilirsiniz:

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

Otomatik haritanın ForSourceMember uzantısı var mı?
Redeemed1

Bunu şu anda yapıyorum, ancak tüm bu Yoksay'ı oluşturmak zorunda DEĞİLDİR ...: /
Tom Stickel

haritayı oluştururken değil, gerçekten harita oluştururken yoksaymanın bir yolu olup olmadığını biliyor musunuz?
Sam, Reinstate Monica'ya


3
Soruda verilen senaryo için, bu kabul edilen cevap olmalıdır. Geçerli kabul edilen yanıt, hedef nesnedeki özelliklerin eşlenmesini yoksayar. Bu soru kaynak nesnede eşleşmeleri yoksaymayı soruyor.
Rob S.

28

Bunu otomatik olarak yapmaya çalışan herkes için, hedef türünde mevcut olmayan özellikleri yok saymak için bu uzantı yöntemini kullanabilirsiniz:

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

aşağıdaki gibi kullanılacak:

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

Can Gencer'e bahşiş için teşekkürler :)

Kaynak: http://cangencer.wordpress.com/2011/06/08/auto-ignore-non-existing-properties-with-automapper/



1
IMapper enjekte edilirken bu çalışmaz. Mapper.GetAllTypeMaps, AutoMapper'ın en son sürümünde mevcut değildir. Ayrıca, haritalarımı bir AutoMapper.Profile içinde ayarlayıp daha sonra IMapper'a enjekte ettiğimde, bu özel durum "Mapper başlatılmadı. Call Initialize'ı uygun yapılandırma ile çalıştırdığımda. statik Mapper.Map yöntemlerine herhangi bir çağrınız yoksa ve ProjectTo veya UseAsDataSource uzantı yöntemlerini kullanıyorsanız, uygun IConfigurationProvider örneğini ilettiğinizden emin olun. "
Ristogod

Ben sadece olsun 'Mapper' does not contain a definition for 'GetAllTypeMaps' [DSSTools]..
Bassie

2
@Bassie Mapper.Configuration.GetAllTypeMaps() Kaynak
Mike Bovenlander

28

Şimdi (AutoMapper 2.0) IgnoreMapbiraz ağır IMHO olan akıcı sözdizimi yerine kullanacağım bir özellik var.


35
Yoksay özniteliği, uygulamanız aracılığıyla otomatik eşleştiriciyi sızdırıyor.
Phill

11
AutoMapper, her yere sızmayı önemsemediğim bir şey. ;)
Pawel Krakowiak

4
Her zaman türetmeyi düşünebilirsiniz IgnoreMapAttribute.
Alapago

1
Bu, birçok nesne arasında devralınan bir temel özelliği yok saymanın iyi bir yoludur. Her eşleme yapılandırmasında yoksaymak zorunda kalmaz.
Chase Florell

23

Bir görünüm modelini bir etki alanı modeliyle eşlerken, hedef üye listesinden ziyade kaynak üye listesini doğrulamak çok daha temiz olabilir

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

Şimdi, alan adı sınıfıma Ignore()her özellik eklediğimde başka bir tane gerektirerek eşleme doğrulamam başarısız oluyor .


7
Bu, sadece çok daha basit bir DTO etki alanı nesne özelliklerinin bir alt kümesini değiştirirken aradığım geldi.
Adam Tolley

5
Bu cevap çocuklar, bu resmi olun, böylece yeni başlayanlar karıştırılmayacak
Piotr M

0

Yok sayılması gereken mülkte IgnoreAttribute kullanılabilir


2
Onun [IgnoreMap]fromIgnoreMapAttribute
fiorebat

-5

Herkese selam Lütfen bu iyi çalışıyor ... kullanın otomatik haritacı için birden kullanın .

        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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.