-1

I use Automapper with EntityFramework Core, and have the following configuration for one of my objects (Couche, having associated an Affaire and a Sol object)

CreateMap<Couche, CoucheDTO>()
    .ForMember(dto => dto.AffaireId, o => o.MapFrom(p => p.Affaire.Id))
    .ForMember(dto => dto.SolId, o => o.MapFrom(p => p.Sol.Id))
    .ForMember(dto => dto.SolNom, o => o.MapFrom(p => p.Sol.Nom))
    .ForMember(dto => dto.SolCode, o => o.MapFrom(p => p.Sol.Code))
    .ReverseMap()
    .ForPath(couche => couche.Affaire, o => o.MapFrom(p => {return null; })) // ???
    .ForPath(couche => couche.Sol, o => o.Ignore()); // ???

When I reverse map (from DTO to Business Object), I need only the correct AffaireId, the Affaire field should be set to null (I don't need to create invalid half-filled objects). How to do it with reverse map? Ignore seem do not put null....

PS. I tried

.ForPath(couche => couche.Affaire, o => o.MapFrom<AffaireDTO>(p => null))
.ForPath(couche => couche.Sol, o => o.MapFrom<AffaireDTO>(p => null));

but get then

InvalidOperationException: No coercion operator is defined between types 'MyApp.Core.Entities.Sol' and 'MyApp.Core.Entities.Affaire'. System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)

DependencyResolutionException: An exception was thrown while activating MyApp.Web.Services.SondageService -> λ:AutoMapper.IMapper -> λ:AutoMapper.IConfigurationProvider. Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action next)

serge
  • 13,940
  • 35
  • 121
  • 205
  • why not using `Ignore` ? https://stackoverflow.com/questions/4987872/ignore-mapping-one-property-with-automapper – demo May 18 '21 at 11:13
  • @demo please read the last sentences from the OP – serge May 18 '21 at 11:23
  • 1
    You might want to consider moving away from _AutoMapper_ because 1) it doesn't scale and 2) there's nothing _"auto"_ about it 3) adds considerable startup time. Addionally the _"DTO"_ concept was a bad habit introduced during ASP.NET MVC and they didn't want their existing model to clash with that from say the DB or comms layers. Unnecessary data transformation is computationally-expensive and you are at risk of data fidelity loss. Consider using a _[Canonical Data Model](https://www.enterpriseintegrationpatterns.com/patterns/messaging/CanonicalDataModel.html)_. –  May 18 '21 at 12:06
  • @MickyD, with pleasure, but what should I do, just remove Automapper? – serge May 18 '21 at 12:54
  • Automapper also makes refactoring and debugging more difficult. Many of the "auto" parts hide bugs that would have been found by the compiler. – Matthew Whited May 18 '21 at 13:05
  • Automapper is bad, OK, but what to replace instead? – serge May 18 '21 at 13:09
  • 1
    @MickyD Any backing for all these claims? For example *it doesn't scale* has been fixed long time ago. And *considerable* startup time. Really? Also, the DTO concept will always be useful for decoupling data layer and other logic. When using AM there needn't even always be intermediary result of entity objects. – Gert Arnold May 18 '21 at 13:12
  • Sure ask anyone in the EAI, ETL industry. If you are doing data transformation via code you are doing it wrong –  May 18 '21 at 14:46

2 Answers2

0

There should be no need to use 'return'.

Try .ForPath(couche => couche.Affaire, o => o.MapFrom(p => null))

serge
  • 13,940
  • 35
  • 121
  • 205
Pad
  • 164
  • 4
  • MapFrom can't infer the generic... probably should specify the type – serge May 18 '21 at 11:25
  • If you intend the value to be null, specifying a type should not be necessary. Let me know if the above has worked for you @Serge – Pad May 18 '21 at 11:32
  • please see the updated OP. If I don't specify a generic type value, the project does not compile – serge May 18 '21 at 12:53
  • https://learn.microsoft.com/en-us/dotnet/csharp/misc/cs0411?f1url=%3FappId%3Droslyn%26k%3Dk(CS0411) – serge May 18 '21 at 13:05
0

Finally, found solution to infere the type... (Affaire)null:

.ForPath(couche => couche.Affaire, o => o.MapFrom(p => (Affaire)null))
.ForPath(couche => couche.Sol, o => o.MapFrom(p => (Sol)null));
serge
  • 13,940
  • 35
  • 121
  • 205