0

I Know this question was answered in another thread. And I tried what was suggested but it still not working.

Here is my entity and model mapping...

cfg.CreateMap<DocumentAmountModel, InputDocumentData>()                    
       .ForMember(d => d.Amounts, o => o.MapFrom(s => s.Amounts));

Mapping for the child Amounts

cfg.CreateMap<ItemAmountModel, Amount>()
            //Ignore the Keys for update
            .ForMember(a => a.Id, o => o.Ignore())
            .ForMember(a => a.ItemId, o => o.Ignore())

And I am trying to ignore the PKs and FKs in the entity from being updated with what is in model.

On the service layer- the entity is loaded with data from Db and then calling the mapper to update all the property other than FK & PK as follows.

var doc = _docDataR.GetAll()
                .Where(d => d.Id==1)
                .SingleOrDefault<InputDocumentData>();

Mapper.Map<DocumentAmountModel, InputDocumentData>(model, doc);

To my surprise, Amount.Id and Amount.ItemId are always updated with 0 on the child Amounts. Am missing anything obvious?

PS: The entity instance "doc" is not proxy, so it is not about being proxy that could have caused improper mapping.

type.parse
  • 21
  • 7
  • _"it is always updated with 0"_ - is it updated though, or is it the property type's default value? Please read [ask] and create a [mcve], too much irrelevant code is missing here. – CodeCaster May 03 '17 at 14:55
  • Thanks CodeCaster, I have updated with more detail in the post now. To Answer your question, the entity is already populated from DB before calling mapper, Ids already have values on it before mapping. But right after executing the Mapper those values(Ids) get changed to 0. – type.parse May 03 '17 at 15:15
  • Your createmap code uses different models than the mapper.map command you show. – Steve Greene May 03 '17 at 15:25
  • Sorry for the missing part (was too desperate after breaking my head for a whole day). The issue was on the child object Amount. Please check my update. – type.parse May 03 '17 at 15:42
  • I think AM is simply replacing your `d.Amounts` collection, hence `Ignore` for the child entities has no effect. – Ivan Stoev May 03 '17 at 16:17
  • This issue now boils down to prevent AM from recreating child object within the collection. Tried applying EqualityComparison along with Ignore. But no luck. – type.parse May 03 '17 at 18:52

1 Answers1

0

When it comes to collection as child, AutoMapper recreates the entity (Destination) collection. In order to instruct AutoMapper to use existing collection, the configuration has to be done as follows...

Step 1: Call the AddCollectionMappers() - this what I missed.

Mapper.Initialize(cfg =>
{
    cfg.AddCollectionMappers(); //This is must        
});

Step 2: Use EqualityComparison method to instruct AM on how to match the item in the source collection to the destination.

Mapper.Initialize(cfg =>
{
    cfg.AddCollectionMappers(); 

    cfg.CreateMap<DocumentAmountModel, InputDocumentData>()                    
       .ForMember(d => d.Amounts, o => o.MapFrom(s => s.Amounts));

   cfg.CreateMap<AmountModel, Amount>()
      .EqualityComparison((model, e) => model.Code == e.Code);
});

Step 3: Ignore any properties such as PKs, FKs that should not be updated from Model

Mapper.Initialize(cfg =>
{
    cfg.AddCollectionMappers(); 

    cfg.CreateMap<DocumentAmountModel, InputDocumentData>()                    
       .ForMember(d => d.Amounts, o => o.MapFrom(s => s.Amounts));

   cfg.CreateMap<AmountModel, Amount>()
      .EqualityComparison((model, e) => model.Code == e.Code)
      .ForMember(e => e.Id, o => o.Ignore());

});

For more detail...

https://github.com/AutoMapper/AutoMapper.Collection

type.parse
  • 21
  • 7