Mapster icon indicating copy to clipboard operation
Mapster copied to clipboard

How to properly map to existing collections?

Open rm-code opened this issue 1 year ago • 3 comments

Let's say I have a situation where an incoming collections needs to be mapped onto an existing collection. src.Adapt(dest) doesn't produce the intended outcome since (I assume) Mapster doesn't know how to match the items in the collection.

using Mapster;
using MapsterTest;
using System.Text.Json;

var collection = new List<NestedCollectionEntity> {
  new NestedCollectionEntity
  {
    Id = 1,
    Value = "NestedCollectionEntity",
    CreatedOn = DateTime.Now,
    CreatedBy = "Me"
  }
};
var dtoCollection = new List<NestedCollectionDto> {
  new NestedCollectionDto
  {
    Id = 1,
    Value = "NestedCollectionDto",
  },
  new NestedCollectionDto
  {
    Id = 2,
    Value = "NestedCollectionDto",
  }
};

Console.WriteLine(JsonSerializer.Serialize(collection, new JsonSerializerOptions { WriteIndented = true }));

dtoCollection.Adapt(collection);

Console.WriteLine("After Mapping");
Console.WriteLine(JsonSerializer.Serialize(collection, new JsonSerializerOptions { WriteIndented = true }));

The output this produces looks like this:

[
  {
    "Id": 1,
    "Value": "NestedCollectionEntity",
    "CreatedOn": "2023-02-17T09:43:38.8157027+01:00",
    "CreatedBy": "Me"
  }
]

After Mapping
[
  {
    "Id": 1,
    "Value": "NestedCollectionDto",
    "CreatedOn": "0001-01-01T00:00:00",
    "CreatedBy": null
  },
  {
    "Id": 2,
    "Value": "NestedCollectionDto",
    "CreatedOn": "0001-01-01T00:00:00",
    "CreatedBy": null
  }
]

Is there an easy way to set this up via Mapster?

My current workaround is to write my own "matching logic":


foreach(var dto in dtoCollection)
{
  var match = collection.FirstOrDefault(o => o.Id == dto.Id);
  if (match != null)
  {
    dto.Adapt(match);
  }
  else
  {
    var n = dto.Adapt<NestedCollectionEntity>();
    collection.Add(n);
  }
}

rm-code avatar Feb 17 '23 08:02 rm-code