2012-07-10 84 views

Trả lời

7

Tôi chưa tìm được cách nào tốt hơn những điều sau đây.

Đây là nguồn và đích.

public class Source 
{ 
    public int Id { get; set; } 
    public string Foo { get; set; } 
} 

public class Destination 
{ 
    public int Id { get; set; } 
    public string Foo { get; set; } 
} 

Xác định trình chuyển đổi (Bạn nên thay đổi Danh sách <> thành bất kỳ loại nào bạn đang sử dụng).

public class CollectionConverter: ITypeConverter<List<Source>, List<Destination>> 
{ 
    public List<Destination> Convert(ResolutionContext context) 
    { 
     var destinationCollection = (List<Destination>)context.DestinationValue; 
     if(destinationCollection == null) 
      destinationCollection = new List<Destination>(); 
     var sourceCollection = (List<Source>)context.SourceValue; 
     foreach(var source in sourceCollection) 
     { 
      Destination matchedDestination = null; 

      foreach(var destination in destinationCollection) 
      { 
       if(destination.Id == source.Id) 
       { 
        Mapper.Map(source, destination); 
        matchedDestination = destination; 
        break; 
       } 
      } 
      if(matchedDestination == null) 
       destinationCollection.Add(Mapper.Map<Destination>(source)); 
     } 
     return destinationCollection; 
    } 
} 

Và đây là cấu hình ánh xạ thực tế và ví dụ.

Mapper.CreateMap<Source,Destination>(); 
Mapper.CreateMap<List<Source>,List<Destination>>().ConvertUsing(new CollectionConverter()); 

var sourceCollection = new List<Source> 
{ 
    new Source{ Id = 1, Foo = "Match"}, 
    new Source{ Id = 2, Foo = "DoesNotMatchWithDestination"} 
}; 
var destinationCollection = new List<Destination> 
{ 
    new Destination{ Id = 1, Foo = "Match"}, 
    new Destination{ Id = 3, Foo = "DoeNotMatchWithSource"} 
}; 
var mergedCollection = Mapper.Map(sourceCollection, destinationCollection); 

Bạn sẽ nhận được kết quả như sau.

Mapping result

1

tôi tìm thấy bài viết này rất hữu ích và như vậy tôi nghĩ tôi sẽ phản hồi trong phiên bản generic của tôi về bộ chuyển đổi loại mà bạn có thể sử dụng để chọn tài sản để phù hợp trên từ từng đối tượng.

Sử dụng tất cả những gì bạn cần làm là:

// Example of usage 
Mapper.CreateMap<UserModel, User>(); 
var converter = CollectionConverterWithIdentityMatching<UserModel, User>.Instance(model => model.Id, user => user.Id); 
Mapper.CreateMap<List<UserModel>, List<User>>().ConvertUsing(converter); 

//The actual converter 
public class CollectionConverterWithIdentityMatching<TSource, TDestination> : 
    ITypeConverter<List<TSource>, List<TDestination>> where TDestination : class 
{ 
    private readonly Func<TSource, object> sourcePrimaryKeyExpression; 
    private readonly Func<TDestination, object> destinationPrimaryKeyExpression; 

    private CollectionConverterWithIdentityMatching(Expression<Func<TSource, object>> sourcePrimaryKey, Expression<Func<TDestination, object>> destinationPrimaryKey) 
    { 
     this.sourcePrimaryKeyExpression = sourcePrimaryKey.Compile(); 
     this.destinationPrimaryKeyExpression = destinationPrimaryKey.Compile(); 
    } 

    public static CollectionConverterWithIdentityMatching<TSource, TDestination> 
     Instance(Expression<Func<TSource, object>> sourcePrimaryKey, Expression<Func<TDestination, object>> destinationPrimaryKey) 
    { 
     return new CollectionConverterWithIdentityMatching<TSource, TDestination>(
      sourcePrimaryKey, destinationPrimaryKey); 
    } 

    public List<TDestination> Convert(ResolutionContext context) 
    { 
     var destinationCollection = (List<TDestination>)context.DestinationValue ?? new List<TDestination>(); 
     var sourceCollection = (List<TSource>)context.SourceValue; 
     foreach (var source in sourceCollection) 
     { 
      TDestination matchedDestination = default(TDestination); 

      foreach (var destination in destinationCollection) 
      { 
       var sourcePrimaryKey = GetPrimaryKey(source, this.sourcePrimaryKeyExpression); 
       var destinationPrimaryKey = GetPrimaryKey(destination, this.destinationPrimaryKeyExpression); 

       if (string.Equals(sourcePrimaryKey, destinationPrimaryKey, StringComparison.OrdinalIgnoreCase)) 
       { 
        Mapper.Map(source, destination); 
        matchedDestination = destination; 
        break; 
       } 
      } 

      if (matchedDestination == null) 
      { 
       destinationCollection.Add(Mapper.Map<TDestination>(source)); 
      } 
     } 

     return destinationCollection; 
    } 

    private string GetPrimaryKey<TObject>(object entity, Func<TObject, object> expression) 
    { 
     var tempId = expression.Invoke((TObject)entity); 
     var id = System.Convert.ToString(tempId); 
     return id; 
    } 
} 
Các vấn đề liên quan