Je viens juste de commencer à utiliser automapper pour mapper les entités DTO <-> et cela semble fonctionner parfaitement.
Dans certains cas particuliers, je souhaite mapper uniquement certaines propriétés et effectuer des vérifications supplémentaires. Sans automapper, le code ressemble à ceci (en utilisant PropertyExtensions de FastFlect):
object target;
object source;
string[] changedPropertyNames = { };
foreach (var changedPropertyName in changedPropertyNames)
{
var newValue = source.GetPropertyValue(changedPropertyName);
target.SetPropertyValue(changedPropertyName, newValue);
}
Bien entendu, ce code ne fonctionnera pas si des conversions de types sont requises. Automapper utilise TypeConverters intégré et j'ai également créé des implémentations spécifiques de TypeConverter.
Maintenant, je me demande s'il est possible de mapper des propriétés individuelles et d'utiliser l'implémentation de conversion de type d'automapper, quelque chose comme ceci
Mapper.Map(source, target, changedPropertyName);
Je pense que plus d'informations sont nécessaires:
J'ai déjà créé des cartes, par exemple.
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
et j'ai également créé une carte avec un convertisseur de type personnalisé pour la propriété nullable dateTime dans CalendarEvent, par exemple.
Mapper.CreateMap<DateTimeOffset?, DateTime?>().ConvertUsing<NullableDateTimeOffsetConverter>();
J'utilise ces cartes dans un contrôleur Web api OData. Lors de la publication de nouveaux EntityDTO, j’utilise
Mapper.Map(entityDto, entity);
et enregistrez l’entité dans un magasin de données.
Mais si vous utilisez PATCH
, un Delta<TDto> entityDto
est transmis à mes méthodes de contrôleur. Par conséquent, je dois appeler entityDto.GetChangedPropertyNames()
et mettre à jour mon entité persistante existante avec les valeurs modifiées.
Fondamentalement, cela fonctionne avec ma solution simple, mais si l’une des propriétés modifiées est par ex. un DateTimeOffset
? J'aimerais utiliser mon NullableDateTimeOffsetConverter
.
Si vous souhaitez uniquement mapper une propriété sélectionnée, procédez comme indiqué ci-dessous.
// Create a map
var map = CreateMap<Source,Target>();
// ingnore all existing binding of property
map.ForAllMembers(opt => opt.Ignore());
// than map property as following
map.ForMember(dest => dest.prop1, opt => opt.MapFrom( src => src.prop1));
map.ForMember(dest => dest.prop2, opt => opt.MapFrom( src => src.prop2));
Vous pouvez faire des projections en utilisant MapFrom method - http://automapper.readthedocs.io/en/latest/Projection.html
Mapper.Map(source, target)
.ForMember(m => m.Property, opt => opt.MapFrom(src => src.ChangedProperty));
Par exemple (en référence à la documentation AutoMapper):
// Model
var calendarEvent = new CalendarEvent
{
Date = new DateTime(2008, 12, 15, 20, 30, 0),
Title = "Company Holiday Party"
};
// Configure AutoMapper
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))
.ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))
.ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute));
Si j'ai bien lu votre question, oui, tant que votre propriété de destination (cible) correspond à votre conversion.
Donc, si je passe d'une string
à une bool
pour une Status
de "A"
ou "I"
(actif/inactif), je peux faire quelque chose comme:
.ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status == "A"))
Et puis, dans l'autre sens, reconvertissez-le:
.ForMember(dest => dest.Status, opt => opt.MapFrom(src => src.Status ? "A" : "I"))
Un exemple de date:
.ForMember(dest => dest.SomeDate, opt => opt.MapFrom(src => src.SomeDate.ToString("M/d/yyyy")));