2012-12-12 11 views
19

AutoMapper'da Inheritance'ı nasıl kullanacağımı inceledim ancak Linq ile tam olarak çalışmayı düşünüyorum. Benim burada eşleştirmeleri tanımladıktanAutoMapper devralma ve Linq

:

CreateMap<Article, ArticleDetailsViewModel>() 
    .Include<Article, ArticleNewsItemDetailsViewModel(); 

CreateMap<Article, ArticleNewsItemDetailsViewModel>(); 

ArticleDetailsViewModelArticleNewsItemDetailsViewModel bir taban sınıfıdır İşte benim kodudur. Ben olsaydı

Şimdi burada sorun yatıyor:

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

görünümü modelinde özelliklerinin tamamı kendi Linq nesne meslektaşı ile aynı adı olduğu için otomatik olarak harita olacaktır. Ancak, bu mümkün değildir Article => ArticleNewsItemDetailsViewModel eşleme kullanıyorum çünkü bunun yerine tanımlamak zorunda kalacak biri olarak her:

.ForMember(x => x.Property1, opt => opt.MapFrom(src => src.ArticleNewsItem.Property1) 

Ben yeni bir görünüm modeline ArticleNewsItemDetailsViewModel tüm özelliklerini hareketli ve o sınıfı olması hakkında düşünce ArticleNewsItemDetailsViewModel içinde bir özellik ve bu iki nesne arasında bir eşleşme olduğu sürece o zaman işe yarayacaktır, ama çok temiz hissetmez.

Bunu yapmaktan kaçınmanın bir yolu var mı? Kafamda bu basitleştirme üzerinde değilim ama sadece Sözünü doğrudan ilişkilendirmenin ekleyemezsiniz eğer

cevap

0

Özür: Bu en basit ve en temiz çözüm Bana göre

CreateMap<ArticleNewsItem, ArticleNewsItemDetailsViewModel>(); 

...

EDIT Üzgünüm, yanlış anladım. Sen

Mapper.CreateMap<Article, ArticleNewsItemDetailsViewModel>().ConstructUsing(ConstructItem) 

ozaman oluşturmak ... .ConstructUsing() veya .ConvertUsing yoluyla özel bir harita() yöntemleri oluşturarak (veya bunu düzensiz şekilde yapıyor) olmadan iç içe geçmiş bir özelliğine bir nesne eşleyemezsiniz senin yöntem

private static ArticleNewsItemDetailsViewModel ConstructItem(Article source) 
    { 
     var newsItem = new ArticleNewsItem 
          { 
           Prop1 = source.Prop1, 
           Prop2 = source.Prop2 
          }; 

     var result = new ArticleNewsItemDetailsViewModel() 
         { 
          ArticleNewsItem = newsItem 
         }; 

     return result; 
    } 

Ancak yine de 'benzeri gibi' eşleştirdiğimize böylece çözümünü uygulamadan yeniden öneriyoruz ... ArticleNewsItemDetailsViewModel inşa etmek. http://automapper.codeplex.com/wikipage?title=Nested%20Mappings

+0

Bunun işe yaramaz bir özelliği, bir iç içe nesnede bir özelliği eşleyen bir özellik olduğu için işe yaramaz.Yuvalanmış bir nesneye eşleme nesnesi olmayan bir özellik – ediblecode

+0

Üzgünüz, yanlış anlaşıldım. Bir nesneyi '.ConstructUsing()' veya '.ConvertUsing()' yöntemleri aracılığıyla özel bir harita oluşturmadan yuvalanmış bir özelliğe eşleyemezsiniz. Gerçekten benzer bir harita çizmelisin. İşte iyi bir örnek: http://automapper.codeplex.com/wikipage?title=Nested%20Mappings – NinjaNye

+0

Soruyu anlamak için teşekkürler. Bununla birlikte, MapTMrt kullanarak haritalamayı tanımlamaya gerek yoktur, çünkü .ForMember kullanılarak ve yuvalanmış özelliklere erişilebilmektedir. – ediblecode

1

aşağıdaki sınıfları Supposing:

public class Article 
    { 
     public string Prop1 { get; set; } 
     public string Prop2 { get; set; } 
     public ArticleNewsItem ArticleNewsItem { get; set; } 
    } 

    public class ArticleDetailsViewModel 
    { 
     public string Prop1 { get; set; } 
    } 

    public class ArticleNewsItemDetailsViewModel : ArticleDetailsViewModel 
    { 
     public string Prop2 { get; set; } 
     public string Prop3 { get; set; } 
    } 

    public class ArticleNewsItem 
    { 
     public string Prop3 { get; set; } 
    } 

haritalama aşağıda gibi görünmelidir:

var res = Mapper.Map<Article, ArticleNewsItemDetailsViewModel>(_article); 
Mapper.Map(_article.ArticleNewsItem, res); 

Üstelik bu iki satır yazmaya önlemek için custom type converter oluşturabilir Burada iyi bir örnektir Her zaman Article'u ArticleNewsItemDetailsViewModel olarak eşleştirmeniz gerekir.

0

Gerekli tüm özelliklerin makalede olduğu varsayılarak, bunu yapmak için bir Custom Value Resolver oluşturabilirsiniz.

public class ArticleNewsItemResolver : ValueResolver<Article, ArticleNewsItem> 
{ 
    protected override ArticleNewsItem ResolveCore(Article source) 
    { 
     return Mapper.DynamicMap<Article, ArticleNewsItem>(source); 
    } 
} 
... 

CreateMap<Article, ArticleNewsItemDetailsViewModel>() 
    .ForMember(src => src.NewsItem, opt => opt.ResolveUsing<ArticleNewsItemResolver>()); 
+0

Aşağı seçmen açıklamak ister misiniz? – James