2013-11-21 14 views
5

Ich habe Zuordnungen wie folgt definiert:AutoMapper - stark typisierten Datensatz

Mapper.CreateMap<DsMyDataSet.TMyRow, MyRowDto>(); 

Die MyRowDto 1: 1 Kopie von TMyRow aber alle Objekte sind Auto Eigenschaften.

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] 
public string PositionFolder{ 
    get { 
     try { 
      return ((string)(this[this.tableTMyDataSet.PositionFolderColumn])); 
     } 
     catch (global::System.InvalidCastException e) { 
      throw new global::System.Data.StrongTypingException("The value for column \'PositionFolder\' in table \'TMyDataSet\' is DBNull.", e); 
     } 
    } 
    set { 
     this[this.tableTMyDataSet.PositionFolderColumn] = value; 
    } 
} 

Als ich nennen:

DsMyDataSet.TMyRow row = ....; 
AutoMapper.Mapper.Map<MyRowDto>(row); 

Ich erhalte die StrongTypingException Ausnahme, da der Wert in der Spalte null ist. Die Eigenschaft kann Nullwerte enthalten, aber stark typisierte Datensätze unterstützen keine Nullwerteigenschaften, und Sie müssen IsNullable instea aufrufen. Wie kann ich dieses Problem im AutoMapper umgehen, so dass die Zuordnungen verarbeitet werden (Ignorieren des Fehlers und Nullwert belassen)?

Antwort

2

Ich denke, der einfachste Weg, um dieses Problem zu lösen, ist die IMemberConfigurationExpression<DsMyDataSet.TMyRow>.Condition() Methode zu verwenden, und verwenden Sie einen try-catch Block zu überprüfen, ob die Quellwert den Zugriff auf eine StrongTypingException wirft.

Hier ist, was Ihr Code enden würde wie die Suche:

Mapper.CreateMap<DsMyDataSet.TMyRow, MyRowDto>() 
     .ForMember(target => target.PositionFolder, 
     options => options.Condition(source => { 
      try { return source.PositionFolder == source.PositionFolder; } 
      catch(StrongTypingException) { return false; } 
     }); 

Wenn dies ein gemeinsames Auftreten ist dann haben Sie ein paar andere Optionen zu vermeiden, für jedes Mitglied alle diesen Code zu schreiben.

Eine Möglichkeit ist eine Erweiterungsmethode zu verwenden:

Mapper 
.CreateMap<Row,RowDto>() 
.ForMember(target => target.PositionFolder, options => options.IfSafeAgainst<Row,StrongTypingException>(source => source.PositionFolder)) 

, wenn die folgenden in der Lösung:

public static class AutoMapperSafeMemberAccessExtension 
{ 
    public static void IfSafeAgainst<T,TException>(this IMemberConfigurationExpression<T> options, Func<T,object> get) 
     where TException : Exception 
    { 
     return options.Condition(source => { 
      try { var value = get(source); return true; } 
      catch(TException) { return false; } 
     }); 
    } 
} 

AutoMapper auch einige in Erweiterungspunkten aufgebaut hat, die auch hier genutzt werden könnte . Ein paar Möglichkeiten, die mich herausspringen sind:

  1. eine IValueResolver Implementierung kundenspezifische definieren. Es gibt bereits eine ähnliche Implementierung in der Lösung, die Sie verwenden könnten: NullReferenceExceptionSwallowingResolver. Sie könnten diesen Code wahrscheinlich kopieren und dann nur den Teil ändern, der angibt, mit welcher Art von Ausnahme Sie arbeiten. Documentation for configuration is on the AutoMapper wiki, aber die Konfiguration Code würde in etwa so aussehen:

    Mapper.CreateMap<Row,RowDto>() 
        .ForMember(target => target.PositionFolder, 
         options => options.ResolveUsing<ExceptionSwallowingValueResolver<StrongTypingException>>()); 
    
2

Verwenden Sie diese Abbildung:

Mapper.CreateMap<DsMyDataSet.TMyRow, MyRowDto>() 
    .ForMember(s => s.PositionFolder, o => o.MapFrom(d => !d.IsPositionFolderNull() ? d.PositionFolder: null)); 
Verwandte Themen