2016-03-16 1 views
6

Sto utilizzando AutoMapper per copiare un oggetto framework entità su un altro database identico. Il problema è che tenta di copiare le tabelle di ricerca.Come ignorare le proprietà in base al tipo

Ho provato a escluderli con AddGlobalIgnore e ShouldMapProperty ma non funziona. AutoMapper prova ancora a copiare queste proprietà.

Ecco il mio codice. Vorrei ignorare le proprietà che iniziano con "LU"

dynamic newObject= new NewObject(); 

MapperConfiguration config = new MapperConfiguration(cfg => 
{ 
    cfg.CreateMissingTypeMaps = true; 
    cfg.AddGlobalIgnore("LU"); 
    cfg.ShouldMapProperty = p => !p.GetType().ToString().StartsWith("LU"); 
    cfg.ShouldMapField = p => !p.GetType().ToString().StartsWith("LU"); 
}); 
IMapper mapper = config.CreateMapper(); 
newObject = mapper.Map(objectToCopy, objectToCopy.GetType(), newObject.GetType()); 

ho anche provato

MapperConfiguration config = new MapperConfiguration(cfg => 
{ 
    cfg.CreateMissingTypeMaps = true; 
    cfg.AddGlobalIgnore("LU"); 
    cfg.ShouldMapProperty = p => !p.PropertyType.Name.StartsWith("LU"); 
    cfg.ShouldMapField = p => !p.FieldType.Name.StartsWith("LU"); 
}); 

e

MapperConfiguration config = new MapperConfiguration(cfg => 
{ 
    cfg.CreateMissingTypeMaps = true; 
    cfg.AddGlobalIgnore("LU"); 
    cfg.ShouldMapProperty = p => !p.Name.StartsWith("LU"); 
    cfg.ShouldMapField = p => !p.Name.StartsWith("LU"); 
}); 
+0

Aspetta, perché hai un oggetto dinamico nel mix lì? –

+0

@JimmyBogard \t Perché 'mapper.Map()' restituisce un oggetto dinamico – Marc

+0

@Silvermind Non ho nessuno strumento per decompilare AutoMapper. Cosa intendi per 'property.Name.StartsWith'? 'p' è un' PropertyInfo' – Marc

risposta

3

Creare la configurazione come profilo separato, quindi aggiungere quel profilo alla configurazione del mappatore.

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic newObject = new NewObject(); 
     var objectToCopy = new ObjectToCopy(); 

     var config = new MapperConfiguration(cfg => 
     { 
      cfg.AddProfile<MyProfile>(); 
     }); 

     var mapper = config.CreateMapper(); 
     mapper.Map(objectToCopy, newObject); 
     // newObject.LU_Ignore = "Original value" 
     // newObject.DoNotIgnore = "New value" 
    } 
} 

class MyProfile : Profile 
{ 
    protected override void Configure() 
    { 
     CreateMissingTypeMaps = true; 
     ShouldMapProperty = p => !p.Name.StartsWith("LU"); // this is the correct way to get the property name 
    } 
} 

class ObjectToCopy 
{ 
    public string LU_Ignore { get; set; } = "New value"; 

    public string DoNotIgnore { get; set; } = "New value"; 
} 


class NewObject 
{ 
    public string LU_Ignore { get; set; } = "Original value"; 

    public string DoNotIgnore { get; set; } = "Original value"; 
} 

Qualcosa sembra goffo su come le configurazioni vengono applicate alla Mapper modulo creato la chiamata mapper.CreateMapper. Ci sto lavorando per vedere se riesco a trovare maggiori informazioni e aggiornerò questa risposta se trovo qualcosa.

+1

Hai ragione. Funziona quando lo crei come profilo separato. Quello è strano. Grazie – Marc

+0

Hai ancora bisogno della chiamata al metodo ShouldMapField? Quando le proprietà vengono modificate, ShouldMapField viene comunque richiamato nel campo di supporto, quindi il codice nel post originale non si comporterebbe come previsto. Ho deciso di non includerlo perché non sembrava essere quello che stavi cercando, ma posso modificare la mia risposta. –

+0

No, non è necessario. Ho provato solo perché 'ShouldMapProperty' non funzionava. Grazie – Marc

0

I wont dire che questo è il migliore (performante o approccio progettuale), ma questo funziona:

public static class AutoExtensions { 
    public static IMappingExpression Ignore(this IMappingExpression expression, Func<PropertyInfo, bool> filter) { 
     foreach (var propertyName in expression 
      .TypeMap 
      .SourceType 
      .GetProperties() 
      .Where(filter) 
      .Select(x=>x.Name)) 
     { 
      expression.ForMember(propertyName, behaviour => behaviour.Ignore()); 
     } 

     return expression; 
    } 
} 

È possibile configurare il mapper come questo (per queste classi di esempio):

public class Client { 
    public string LUName { get; set; } 
    public string Dno { get; set; } 
} 

public class ClientDTO 
{ 
    public string LUName { get; set; } 
    public string Dno { get; set; } 
} 

e verificare il lavoro svolto in questo modo:

private static void ConfigAndTestMapper() { 
     var config = new MapperConfiguration(cfg =>{ 
      cfg.CreateMap(typeof (Client), typeof (ClientDTO)) 
       .Ignore(x => x.Name.StartsWith("LU")); 
     }); 

     var mapper = config.CreateMapper(); 
     var result = mapper.Map<ClientDTO>(new Client() {LUName = "Name", Dno = "Dno"}); 

     var isIgnored = result.LUName == null; 
    } 

PS: questo è anche abbastanza "hacker", in quanto si cerca di mappare tutti i tipi di proprietà lì (solo in lettura/non pubblico, ecc.) quindi portalo con un pizzico di sale.