2012-06-29 31 views
29

Tôi có giao diện công khai mà tôi đang cố gắng ánh xạ hai bảng kê khác nhau cho nhau. Tôi cố gắng để sử dụng đoạn mã sau:Làm thế nào tôi có thể ánh xạ giữa hai enums bằng Automapper?

Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>(); 

Khi điều đó không làm việc, tôi đã cố gắng:

Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>().ConvertUsing(x => (Common.ValidationResultType)((int)x)); 

Nhưng điều đó dường như không làm việc, hoặc. Có anyway để có được automapper để xử lý kịch bản này?

+0

Bạn có gặp lỗi không? Cái gì không hiệu quả? –

+0

Tôi đã nhận được "Cấu hình bản đồ loại thiếu hoặc ánh xạ không được hỗ trợ". lỗi. –

+3

Bạn có thể đăng các enums của mình không? –

Trả lời

33

Bạn không cần phải tạo CreateMap cho các loại enum. Chỉ cần thoát khỏi cuộc gọi CreateMap và nó sẽ hoạt động, miễn là tên và/hoặc giá trị khớp với nhau giữa các loại enum.

+0

Khi thực hiện theo thông lệ này, nó có thích ứng với giá trị enum hoặc tên thành viên không? –

+9

Điều gì sẽ xảy ra nếu tên và giá trị không khớp? – Darcy

+1

Sau đó, bạn cần tạo trình chuyển đổi loại tùy chỉnh. –

2

Dưới đây là một khả năng để thực hiện chuyển đổi giữa hai loại Enum có cả hai giá trị khác nhau, trong khi vẫn sử dụng AutoMapper. Trong trường hợp của tôi, tôi cần sử dụng AutoMapper vì các kiểu Enum là các thuộc tính trên các thực thể khác đang được AutoMapper chuyển đổi; sử dụng AutoMapper cho các thực thể này là một yêu cầu.

Bước đầu tiên là để thiết lập cấu hình Mapper như vậy:

Mapper.CreateMap<EnumSrc, EnumDst>() 
    .ConstructUsing(EnumConversion.FromSrcToDst); 

Calling .ConstructUsing(...) cho phép chúng ta vượt qua trong phương pháp riêng của chúng tôi để làm việc chuyển đổi. Phương pháp chuyển đổi khá thẳng về phía trước:

public class EnumConversion 
{ 
    internal static EnumDst FromSrcToDst(ResolutionContext arg) 
    { 
     EnumSrc value = (EnumSrc)arg.SourceValue; 
     switch(value) 
     { 
      case EnumSrc.Option1: 
       return EnumDst.Choice1; 
      case EnumSrc.Option2: 
       return EnumDst.Choice2; 
      case EnumSrc.Option3: 
       return EnumDst.Choice3; 
      default: 
       return EnumDst.None; 
     } 
    } 
} 

Chúng tôi chỉ đơn giản là switch thông qua giá trị của nguồn Enum và trả về giá trị thích hợp Giá trị enum tùy ý. AutoMapper sẽ lo phần còn lại.

+1

Tôi đã thử triển khai này và nó chỉ được ánh xạ dựa trên giá trị số nguyên (AutoMapper 3.3.1). Tôi sẽ thêm câu trả lời của tôi làm việc dưới đây – Neil

2

Các câu trả lời khác ở đây không hiệu quả đối với tôi.

Bạn cần phải tạo ra một lớp mà thực hiện:

ITypeConvertor<SourceType ,DestinationType> 

Vì vậy, như một ví dụ

Mapper.CreateMap<EnumType1.VatLevel, EnumType2.VatRateLevel>() 
     .ConvertUsing(VatLevelConvertor); 

Và các lớp:

internal class VatLevelConvertor : ITypeConverter<EnumType1.VatLevel, EnumType2.VatRateLevel> 
{ 
    public EnumType2.VatRateLevel Convert(ResolutionContext context) 
    { 
     EnumType1.VatLevel value = (EnumType1.VatLevel)context.SourceValue; 
     switch (value) 
     { 
      case EnumType1.VatLevel.Standard: 
       return EnumType2.VatRateLevel.Normal; 
      case EnumType1.VatLevel.Reduced: 
       return EnumType2.VatRateLevel.Lower; 
      case EnumType1.VatLevel.SuperReduced: 
       return EnumType2.VatRateLevel.Other; 
      default: 
       return EnumType2.VatRateLevel.Other; 
     } 
    } 
} 
28

Ngoài ra để viết bộ chuyển đổi tùy chỉnh, chỉ cần sử dụng ConvertUsing()

Mapper.CreateMap<EnumSrc, EnumDst>().ConvertUsing(value => 
{ 
    switch(value) 
    { 
     case EnumSrc.Option1: 
      return EnumDst.Choice1; 
     case EnumSrc.Option2: 
      return EnumDst.Choice2; 
     case EnumSrc.Option3: 
      return EnumDst.Choice3; 
     default: 
      return EnumDst.None; 
    } 
}); 
4

Cách đơn giản tôi thấy rằng công việc đối với tôi là như sau:

Enum của tôi là một lồng nhau trong lớp khác vì vậy tôi sử dụng phương pháp ForMember và MapFrom như sau:

Mapper.CreateMap<ProblematicCustomer, ProblematicCustomerViewModel>()     
      .ForMember(m=> m.ProblemType, opt=> opt.MapFrom(x=> (ProblemTypeViewModel)(int)x.ProblemType)) 
      .ForMember(m=> m.JudgmentType, opt=> opt.MapFrom(x=> (JudgmentTypeViewModel)(int)x.JudgmentType)); 

Các ProblemType và JudgmentType là Enums. Và Mô hình Chế độ xem có liên quan của họ là ProblemTypeViewModel và JudgmentTypeViewModel với cùng các thành viên như Mô hình liên quan của họ.

Mặc dù tôi không kiểm tra, Nhưng tôi nghĩ rằng phía dưới đường nên làm việc cho bạn:

Mapper.CreateMap<Contract_1_1_0.ValidationResultType, Common.ValidationResultType>() 
      .ForMember(m=> m, opt => opt.MapFrom(x=> (Common.ValidationResultType)(int)x); 

hy vọng nó giúp.

2

Tôi đang cố gắng ánh xạ giữa các enums "bình đẳng" bằng Automapper, nhưng tiếc là nó không hoạt động. Tôi nghi ngờ vấn đề là một sự khác biệt trong vỏ:

public enum Foo { 
    val1, 
    val2 
} 

public enum Bar { 
    Val1, 
    Val2 
} 

Foo là một cái gì đó tự động tạo ra từ một XSD, và các nhà cung cấp sucks. Ngoài ra còn có ba mươi-một số giá trị và tôi không muốn đặt một switch mà lớn bất cứ nơi nào cho một cái gì đó rất ngớ ngẩn.

Cách tiếp cận tôi mất là để chuyển đổi các giá trị nguồn để chuỗi và phân tích rằng giá trị đích:

static Foo ConvertEnum(Bar source) 
{ 
    Foo result; 
    var parsed = Enum.TryParse(source.ToString().ToLowerInvariant(), true, out result); 
    if(!parsed) 
     // throw or return default value 
     throw new ArgumentOutOfRangeException("source", source, "Unknown source value"); 
    return result; 
} 

Tất nhiên, đây chỉ hoạt động nếu enums của bạn chỉ có sự khác biệt trong vỏ. Bạn có thể làm cho nó phức tạp hơn bằng cách làm sạch chuỗi đầu vào (ví dụ: xóa dấu gạch dưới, v.v.) hoặc bằng cách thêm công cụ vào chuỗi theo yêu cầu.

2

Chỉ cần tạo một người lập bản đồ cho hai Enums, đúng vậy! Automapper sẽ ánh xạ bằng giá trị khớp hoặc giá trị chỉ số của Enum. (Ví dụ Draft -> Bước 1)

public enum SourceStatus 
{ 
    Draft, 
    Submitted, 
    Deleted 
} 

public enum DestinationStatus 
{ 
    Step1, 
    Step2, 
    Step3 
} 

public class SourceObj 
{ 
    public SourceStatus Status { get; set; } 
} 

public class DestinationObj 
{ 
    public DestinationStatus Status { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     //Static APi style - this is obsolete now. From Version 5.0 onwards this will be removed. 
     SourceObj mySrcObj = new SourceObj(); 
     mySrcObj.Status = SourceStatus.Deleted; 

     Mapper.CreateMap<SourceStatus, DestinationStatus>(); 
     Mapper.CreateMap<SourceObj, DestinationObj>(); 

     DestinationObj myDestObj = Mapper.Map<SourceObj, DestinationObj>(mySrcObj); 

     //New way of doing it 
     SourceObj mySrcObj2 = new SourceObj(); 
     mySrcObj2.Status = SourceStatus.Draft; 

     var config = new MapperConfiguration(cfg => 
     { 
      cfg.CreateMap<SourceObj, DestinationObj>(); 
     }); 

     IMapper mapper = config.CreateMapper(); 
     var source = new SourceObj(); 
     var dest = mapper.Map<SourceObj, DestinationObj>(source); 



    } 
} 
6

My Automapper hoạt động theo cách này:

Nếu tôi tạo ra một bản đồ: Automapper sẽ phù hợp enums theo giá trị, ngay cả khi tên phù hợp một cách hoàn hảo.

Nếu tôi không tạo bản đồ: Máy tự động sẽ khớp với enums theo tên.

Các vấn đề liên quan