2011-11-04 59 views
5

Số phát hành Dường như điều kiện bị bỏ qua. Đây là kịch bản của tôi:Điều kiện của Automapper bị bỏ qua

Nguồn lớp

public class Source 
{ 
    public IEnumerable<Enum1> Prop1{ get; set; } 

    public IEnumerable<Enum2> Prop2{ get; set; } 

    public IEnumerable<Enum3> Prop3{ get; set; } 
} 

Các enums subclass từ một byte và được trang trí với [Flags]. Lớp đích đơn giản chứa các thuộc tính như Enum1, Enum2 và Enum3 tiếp theo giá trị bitwise "tổng". Vì vậy, trong essense nếu Enumeration chứa Enum1.value !, Enum1.Value2 và Enum1.Value3, đích sẽ chứa giá trị bitwise của Enum1.Value1 | Enum1.Value2 | Enum1.Value3

lớp Destination

public Enum1 Prop1 { get; set; } 

    public Enum2 Prop2 { get; set; } 

    public Enum3 Prop3 { get; set; } 

AutoMapper Mapping

Mapper.CreateMap<Source, Destination>() 
      .ForMember(m => m.Prop1, o => 
       { 
        o.Condition(c => !c.IsSourceValueNull); 
        o.MapFrom(f => f.Prop1.Aggregate((current, next) => current | next)); 
       }) 
      .ForMember(m => m.Prop2, o => 
      { 
       o.Condition(c => !c.IsSourceValueNull); 
       o.MapFrom(f => f.Prop2.Aggregate((current, next) => current | next)); 
      }) 
      .ForMember(m => m.Prop3, o => 
      { 
       o.Condition(c => !c.IsSourceValueNull); 
       o.MapFrom(f => f.Prop3.Aggregate((current, next) => current | next)); 
      }); 

Việc lập bản đồ hoạt động tốt khi các tính chất bên trong không phải là null và lập bản đồ thành công và đặt nơi một cách chính xác. Tuy nhiên, tôi muốn bỏ qua ánh xạ khi giá trị nguồn thành viên là null (khi Prop1 là null, sau đó bỏ qua ánh xạ).

Tôi có thể thấy từ việc gỡ lỗi Source.Prop1 đó là rỗng. Các điều kiện được hoàn toàn bị bỏ qua và nhận được ngoại lệ nói rằng giá trị là null.

Trying to map Source to Destination. Destination property: Prop1. Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. --> Value cannot be null. Parameter name: source 

Tôi không chắc liệu IsSourceValueNull kiểm tra Prop1 hay lớp Nguồn thực tế không rỗng. Chỉ thành viên Prop1 là null.

Bất kỳ trợ giúp nào đều được đánh giá cao.

Trả lời

6

Tôi nghĩ rằng bạn cần phải làm như ConditionMapFrom theo hai bước:

.ForMember(c => c.Prop1, o => o.Condition(c => !c.IsSourceValueNull)); 
.ForMember(c => c.Prop1, o => o.MapFrom(f => f.Prop1.Aggregate(...)); 

Các MapFrom sẽ không bao giờ được sử dụng nếu Điều kiện là false.

EDIT

Hmmm ... Đó dường như không làm việc. Tôi nghĩ tôi đã sử dụng nó trước một nơi nào đó. Bạn chỉ có thể sử dụng MapFrom:

.MapFrom(f => f.Prop1 == null ? null : f.Prop1.Aggregate(...)); 
+0

Cảm ơn Patrick. Tôi nhận được cùng một ngoại lệ chính xác bằng cách tách ra điều này. – TimJohnson

+0

Tôi nghĩ tôi đã làm điều đó trước đây. Một điều có thể là c.IsSourceValueNull có thể đại diện cho dù toàn bộ đối tượng nguồn được ánh xạ là null. Tôi tự hỏi nếu nó nên là "c => c.Prop1! = Null"? – PatrickSteele

+0

Không thể tìm thấy mẫu mã sử dụng "Điều kiện". Lấy làm tiếc. Tôi đoán bạn luôn có thể làm: o.MapFrom (f => f.Prop1 == null? Null: f.Prop1.Aggregate (...)) – PatrickSteele

2

IMO, đây thực sự là lỗi trong Tự động sửa lỗi EnumMapper. Các điều kiện báo cáo, như bạn có chúng ở trên, nên làm việc tốt. Ví dụ, khi ánh xạ từ một loại bê tông khác các TypeMapMapper sẽ gọi một cách chính xác các điều kiện:

object mappedObject = !context.TypeMap.ShouldAssignValue(context) ? null : mapperToUse.Map(context, mapper); 

Mà cuối cùng gọi defined condition:

public bool ShouldAssignValue(ResolutionContext context) 
    { 
     return _condition == null || _condition(context); 
    } 

Nhưng EnumMapper không gọi phương thức ShouldAssignValue của TypeMap để tìm hiểu xem liệu nó có thực sự ánh xạ trường đó hay không. Tương tự như vậy, tôi không thấy bất kỳ tham chiếu nào đến AfterMap do đó không chắc rằng bất kỳ điều gì được xác định cũng sẽ không hoạt động.

+0

Nộp theo số phát hành # 143 với một testcase: https://github.com/AutoMapper/AutoMapper/issues/143 –

+0

Cảm ơn. Điều đó có ý nghĩa. – TimJohnson

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