I have a Member named "Name" and I'm using AutoMapper to map between my ViewModel and my base Model. However, I also have a method named "GetName()" on a separate ViewModel which seems to be overriding my "Name" member's 'get' on the actual model.
I've since renamed the method to "GetFullName()" and this is no longer a problem.
This work-around works just fine, however, I would like to know what override in AutoMapper I can implement to let it know to not map function values like "GetName()" to a member's 'get'.
You can override via:
Mapper.CreateMap<Foo, FooDto>()
.ForMember(d => d.Name, opt => opt.MapFrom(src => src.Name));
Related
I have an EF model with Vehicle.Applications.Warranties, and I'm mapping to VehicleDto. I want the Warranties in VehicleDto and I have a WarrantyDto to receive it. I keep getting null for Warranties, though.
I'm using a projection which might be wrong, but from the AutoMapper docs, I can't see any other way to access IQueryable interfaces like this.
This is what I've tried. Doesn't seem to work.
CreateMap<Vehicle, VehicleDto>();
CreateMap<Warranty, WarrantyDto>();
CreateProjection<Vehicle, VehicleDto>().ForMember(d => d.Warranties, opt => opt.MapFrom(s => s.Applications.Select(a => a.Warranties)))
public class ProfileA : ProfileB
{
CreateMap<Source, Destination>(d => d.Age, opt => opt.UseValue(14));
}
public class ProfileB : Profile
{
public ProfileB()
{
CreateMap<Source, Destination>(d => d.Name, opt => opt.UseValue("qqq"));
}
}
Even though the maps are on same source and destination type I want the separation by creating a base Profile then inheriting and creating more specific Profiles. But as with above code only ProfileA's mappers will be applied.
How can I achieve such feat using AutoMapper or is it even considered a good practice for AutoMapper?
Having the same map in different profiles is an anti-pattern and is not allowed by default. There is only one map and overriding it in this way only makes things difficult. See this. It can be overridden.
I'm trying to configure a simple AutoMapper mapping from an Entity Framework entity to a view model object. It mostly works but in the view model I have an int field to hold a count. This field does not exist in the source entity.
cfg.CreateMap<Feed, FeedVM>()
.ForMember(dest => dest.Count, opt => opt.MapFrom(src => src.Orders.Count()));
When I check the validity of the mapping I get the following error message:
The following property on Feed cannot be mapped:
Add a custom mapping expression, ignore, add a custom resolver, or modify the destination type Feed.
Context:
Mapping from type FeedVM to Feed
If I understand the Automapper syntax correctly I am mapping from Feed to FeedVM but the error message seems to indicate that I am mapping from FeedVM to Feed.
What should I be doing to map the value 42 to the Count field in FeedVM?
You should use ResolveUsing:
cfg.CreateMap<Feed, FeedVM>()
.ForMember(dest => dest.Count, opt => opt.ResolveUsing(src => src.Orders.Count()));
Update
John indicates in the comment below that the mappings are correct, the problem lies in a mapping for another entity that is related to Feed. In that entity he is mapping both directions.
Is it possible to configure/use AutoMapper in such a way where when i create an object from a mapping i allow all properties and child collections, however, when it comes to performing an update to existing object, the mapping will ignore child collection properties as they will be empty but i dont want them removed.
This is because i am working with a WCF service that sends delta changes to objects and most of my model works in a tree hierarchy:
Parent
List<Child> Children
ParentDto
List<ChildDto> Children
config.CreateMap<ParentDto, Parent>();
config.CreateMap<ChildDto, ChildDto>();
This works well and the child collection is populated first time round. However, there are scenarios where i will send the ParentDto across with just the parent POCO property changes (such as a datetime change), but the child list will be empty as none of them have changed. Normally i would do:
_Mapper.Map<ParentDto,Parent>(dto, local)
but obviously that will change the entire tree and populate the local object with an empty child list. Massively simplifying but would something like
_Mapper.Map<ParentDto, Parent>(dto, local).Ignore(p => p.Children)
be possible?
I should also add I am using SimpleInjector DI framework. So perhaps there is a way to register 2 configurations, one with ignore and one without?
Use .ForMember(dest => dest.A, opt => opt.MapFrom(src => src.B)) for mapping only properties you need to update.
For those who still struggle to find this. You can use Autommapper Conditional Mapping.
You can do it like this, in the Initialize
config.CreateMap<ChildDto, ChildDto>().ForMember(dest => dest.Children, opt => opt.Condition(source => source.TriggerChildMap));
This will ignore mapping based on the property in source object. To map against existing destination you need to use
Mapper.Map(source, destination) method and not the var result = Mapper.Map<ChildDto>(source) property.
In my project I have a one to many relationship from Client -> Projects. As such, in one of my views, I am trying to show all of the Projects that belong to that Client. So I have an IEnumerable<ProjectDetailsViewModel> that represents all of the clients projects.
The problem is that the ProjectDetailsViewModel has a ClientDetailsViewModel which then has an IEnumerable<ProjectDetailsViewModel> and so on and so forth creating an endless loop of identical entities.
Is this where it is appropriate to use the MaxDepth() method on that .ForMember()? If so, how do I use it in this case, and if not, what is the solution?
I have tried MaxDepth(1) on the Client and whilst this prevents the StackOverflow exception, it then doesn't hold any data in the view model for that client.
The problem was that I explicitly called AutoMapper from with the AutoMapConfig as such:
.ForMember(x => x.Client, opt => opt.MapFrom(src =>
AutoMapper.Mapper.Map<ClientDetailsViewModel>(src.Client)))
If I just define it as:
.ForMember(x => x.Client, opt => opt.MapFrom(src => src.Client))
AutoMapper will know to stop after 1 recursion, and as I already have a map from Client -> ClientDetailsViewModel there is no problem.