Automapper: Update Property Values Without Creating a New Object

Automapper: Update property values without creating a new object

Use the overload that takes the existing destination:

Mapper.Map<Source, Destination>(source, destination);

Yes, it returns the destination object, but that's just for some other obscure scenarios. It's the same object.

How to prevent AutoMapper from overwriting existing values on destination object?

AutoMapper says this in the documentation:

When mapping to an existing collection, the destination collection is cleared first. If this is not what you want, take a look at AutoMapper.Collection.

AutoMapper.Collection, according to the documentation, does:

Adds ability to map collections to existing collections without re-creating the collection object.

Will Add/Update/Delete items from a preexisting collection object based on user defined equivalency between the collection's generic item type from the source collection and the destination collection.

After installing AutoMapper.Collection I've updated the AutoMapper configuration as follows:

var mapperConfig = new MapperConfiguration(exp =>
{
exp.AddCollectionMappers();

exp.CreateMap<TopEntity, TopEntityViewModel>();

exp.CreateMap<BottomEntity, BottomEntityViewModel>();

exp.CreateMap<TopEntityViewModel, TopEntity>();

exp.CreateMap<BottomEntityViewModel, BottomEntity>()
.ForMember(dest => dest.TopId, opts => opts.Ignore())
.EqualityComparison((src, dest) => src.Id == dest.Id);
});

The line .EqualityComparison((src, dest) => src.Id == dest.Id); adds an equality comparison that AutoMapper will use as follows:

  • If Ids match, then AutoMapper will map BottomEntityViewModel to BottomEntity
  • If BottomEntityViewModel exists and BottomEntity doesn't, then AutoMapper will add a new BottomEntity mapped from BottomEntityViewModel to the collection
  • If BottomEntity exists and BottomEntityViewModel doesn't, then AutoMapper will remove BottomEntity from collection

This behavior of AutoMapper.Collection is described here

Working example: https://dotnetfiddle.net/tnaUjY

Thanks to Lucian Bargaoanu for pointing me to the correct direction

Automapper to update an existing object as opposed to creating a new one

It is not adviced to use Automapper to map a model to your Entity. Dependencies or Informations can be overwritten if it isn't used wisely.
But to use it as you want, you only need to create a map from your Model to your Entity and then call

Mapper.Map(myModel, myEntity);

The mapping to entity Problem

I guess you use a ORM like NHibernate or EF, then your Entites are Proxies, where references are proxies too and so on. Now lets imagine you have an ASP.NET MVC Project and you map your Entity to your ViewModel. You show your Model in your View as a form, but you only show the properties that you need in your view, not all that are set in your ViewModel. Then the user sends the Form back to you and your Controller gets the ViewModel back, but this time not all Properties are set, because your View only knew the ones that were shown. If you map your ViewModel back to your entity, all unitialized properties are in there default state and will overwrite the valid data f rom your entity.

Another Problem is, that AutoMapper uses Reflections to set the Properties. Normally the right to exist for an ORM is the possibility to easy implement an DomainLayer. The DomainLayer has some Validations, Calculation... on the Entity itself. If now the Properties set with Reflection it would ignore the Business logic and no Validation, Calculations.... would be executed.

So my advice is, Don't map to Entities ;)

Automapper - update existing instance

The Map<...>() method has an overload where you can supply the destination object. So it's basically

Dest dest = new Dest();
mapper.Map<SourceA, Dest>(sourceA.Value, dest);
//...
mapper.Map<SourceB, Dest>(sourceB.Value, dest);

Automapper only creates new object without map

Add setter to each property in DcMarkupValue.

public class DcMarkupValue
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public decimal MarkupPrice { get; set; }
public decimal MarkupChange { get; set; }
}

EF Core entity is added instead of update when using AutoMapper

mapper.map<Seo>(text) can't relate the entity because it makes new model.

you can try this:

_mapper.map(text,text.Seo); //don't assign to variable


Related Topics



Leave a reply



Submit