2012-05-09 38 views
5

ben şöyle bir Dictionary<User, bool>AutoMapper Sözlük

Kullanıcı olduğunu var düzleşme:

public class User { 
    public string Username { get; set; } 
    public string Avatar { get; set; 
} 

ikinci tip, bool, kullanıcının kullanıcı oturum arkadaşı olup olmadığını belirtir.

public class UserDto { 
    public string Username { get; set; } 
    public string Avatar { get; set; } 
    public bool IsFriend { get; set; } 
} 

IsFriend sözlüğün değerini temsil eder: olarak Ben List<UserDto içine bu Sözlüğü düzleştirmek istiyorum> UserDto tanımlanır.

Bunu nasıl yapabilirim?

+0

Herhangi biri bana otomatik bir araç kullanan bir yöntem verebilirse, sorudaki cevabı değiştireceğim! – reach4thelasers

cevap

11

Sen sadece bir haritalama ile bunu mümkün olmalıdır:

Bir KeyValuePair<User, bool>UserDto eşlemek gerekir. Bu, AutoMapper'ın sözlüğün içeriğini List<T>'un içeriğine eşleştirebilmemiz için nihayetinde oluşturuyoruz (daha fazla açıklama this answer'da bulunabilir). Sonra

Mapper.CreateMap<KeyValuePair<User, bool>, UserDto>() 
    .ForMember(dest => dest.Username, opt => opt.MapFrom(src => src.Key.UserName)) 
    .ForMember(dest => dest.Avatar, opt => opt.MapFrom(src => src.Key.Avatar)) 
    .ForMember(dest => dest.IsFriend, opt => opt.MapFrom(src => src.Value)); 

, sizin .Map çağrısında eşleme kullanın: AutoMapper senin kadar uzun DictionaryList bir de bağlamakta işleyebilir olarak

Mapper.Map<Dictionary<User, bool>, List<UserDto>>(...); 

Sen koleksiyonları kendilerini haritasına gerek yok' ve koleksiyonların içeriğini birbirleriyle eşleştirdik (bizim durumumuzda KeyValuePair<User, bool> - UserDto).


Düzenleme: Burada haritalama gerektirmeyen başka bir çözüm var her User mülkiyet UserDto için: Ben geç kaldım biliyorum AutoMapper 2.0

+0

Bu çözüm, Kullanıcı ve Kullanıcı'ya bir özellik eklediğimde, eşlemeyi değiştirmem gerekiyor. Bireysel özelliklerin haritalanmasını gerektirmeyen bir çözüm olmasını tercih ederim. Otomapperın nasıl çalışması gerektiği değil. – reach4thelasers

+1

"Eğer automapper'ın çalışması böyle olmaz" ise, API neden bir '.ForMember' yöntemi sağlıyor? Yine de, daha "otomatik" bir çözüm bulmaya çalışacağım. –

+1

@ reach4thelasers: Başka bir çözüm daha eklemiş olabileceğimi düşündüm. –

-1

Böyle basit bir şey için hızlı bir LINQ sorgusu yapacaktır. dict varsayarsak senin Dictionary<User,bool> geçerli:

var conv = from kvp in dict 
      select new UserDto 
        { 
         Avatar = kvp.Key.Avatar, 
         IsFriend = kvp.Value, 
         Username = kvp.Key.Username 
        }; 
0

kullanma

Mapper.CreateMap<User, UserDto>(); 
Mapper.CreateMap<KeyValuePair<User, bool>, UserDto>() 
    .ConstructUsing(src => Mapper.Map<User, UserDto>(src.Key)) 
    .ForMember(dest => dest.IsFriend, opt => opt.MapFrom(src => src.Value)); 

Bu oyuna, henüz bir sözlük bir .Net türüne eşleme için daha genel bir çözüm gibi görünüyor (si mple)

automapper kullanılarak
public static IMappingExpression<Dictionary<string, string>, TDestination> ConvertFromDictionary<TDestination>(
     this IMappingExpression<Dictionary<string, string>, TDestination> exp) 
{ 
    foreach (PropertyInfo pi in typeof(TDestination).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 
    { 
     exp.ForMember(propertyName, cfg => cfg.MapFrom(r => r[propertyName])); 
    } 
    return exp; 
} 

bu

Mapper.CreateMap<Dictionary<string, string>, TDestination>().ConvertFromDictionary(); 

TDestination yapabilirsiniz NET basit tür gibi kullanın. Karmaşık türler için, bir Func/Action temsilcisini ve bu işlevi kullanarak haritayı sağlayabilirsiniz. (Her biri için yukarıdakilerin içinde)

Ör.

if (customPropNameMapFunc != null && !string.IsNullOrEmpty(customPropNameMapFunc(propertyName))) 
{ 
    exp.ForMember(propertyName, cfg => cfg.MapFrom(r => r[customPropNameMapFunc(propertyName)])); 
}