Search code examples
c#mappingwebapi

What is the core difference between the map(s,d) and map<d>(s)


I have a Api method PATCH like this

[HttpPatch("{id}")]
public async Task<IActionResult>UpdateCity(int id, [FromBody] JsonPatchDocument<CityUpdateDto> patchDoc)
{
    var cityFromRepo = await _citiesRepository.GetCityById(id);
    var cityToPatch = _mapper.Map<CityUpdateDto>(cityFromRepo);

    Action<JsonPatchError> errorAction = error =>{ ModelState.AddModelError(error.Operation.path, error.ErrorMessage);};
    patchDoc.ApplyTo(cityToPatch, errorAction);
     //this line below
    _mapper.Map(cityToPatch, cityFromRepo);
    await _citiesRepository.SaveChangesAsync();

    return Ok("Done update");
}

This was original method and it is updating the data.
but id i change the code to


        [HttpPatch("{id}")]
        public async Task<IActionResult>UpdateCity(int id, [FromBody] JsonPatchDocument<CityUpdateDto> patchDoc)
        {
            var cityFromRepo = await _citiesRepository.GetCityById(id);
            var cityToPatch = _mapper.Map<CityUpdateDto>(cityFromRepo);

            Action<JsonPatchError> errorAction = error =>{ ModelState.AddModelError(error.Operation.path, error.ErrorMessage);};
            patchDoc.ApplyTo(cityToPatch, errorAction);
             //changed here
            _mapper.Map<City>(cityToPatch);
            await _citiesRepository.SaveChangesAsync();

            return Ok("Done update");
        }

now my patch method is not working.

I want to know the reason and a explanation

 _mapper.Map(cityToPatch, cityFromRepo);
  mapper.map(T Source,T Destination)

VS

 _mapper.Map<City> (cityFromRepo);
 mapper.Map<T Destination> (T Source);

plese tell me a detailed answer.


Solution

  • One returns a new instance of the destination type and the other will map into an existing instance.

    The most common usage is to return a new instance, for example:

    var source = new FooSource
    {
        MyProperty = 123 
    };
    
    var destination = mapper.Map<FooDestination>(source);
    

    However, if you already have an instance you can map properties into that:

    var source = new FooSource
    {
        MyProperty = 123 
    };
    
    var destination = new FooDestination();
    Console.WriteLine(destination.MyProperty);
    // Output: 0
    
    mapper.Map(source, destination);
    Console.WriteLine(destination.MyProperty);
    // Output: 123
    

    Note that the latter overload will also return the same object, for example:

    var destination1 = new FooDestination();
    var destination2 = mapper.Map(source, destination);
    
    Console.WriteLine(object.ReferenceEquals(destination1, destination2));
    // True