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
How to Add a .Dll Reference to a Project in Visual Studio
Parsing Visual Studio Solution Files
Page.Datacontext Not Inherited from Parent Frame
Pair-Wise Iteration in C# or Sliding Window Enumerator
Why Is the Iteration Variable in a C# Foreach Statement Read-Only
5.7.57 Smtp - Client Was Not Authenticated to Send Anonymous Mail During Mail from Error
How Does Hashset Compare Elements for Equality
How to Test If Type Is Primitive
Image Sequence to Video Stream
To Return Iqueryable<T> or Not Return Iqueryable<T>
In C#, What Happens When You Call an Extension Method on a Null Object
How to Keep the Delimiters of Regex.Split
How to Elegantly Check If a Number Is Within a Range
Difference Between Await and Continuewith
Retrying Httpclient Unsuccessful Requests