I'm seeing different behavior mapping TypeView
-> Type
when I map the types directly, vs when that type is used in another type.
In this example I want to map from the View
types into the non-View
types:
//db model
public class TestClass
{
public DateTime CreateDate { get; set; }
public List<ChildClass> ChildClasses { get; set; }
}
public class ChildClass
{
public long Id { get; set; }
public DateTime CreateDate { get; set; }
}
//view model from client
public class TestClassView
{
public long Id { get; set; }
public DateTime CreateDate { get; set; }
public List<ChildClassView> ChildClasses { get; set; }
}
public class ChildClassView
{
public DateTime CreateDate { get; set; }
}
In this case I don't want CreateDate
to be settable by the view, as it is a generated field. So define my mapping profiles to ignore it on both the parent and child views:
CreateMap<TestClassView, TestClass>()
.ForMember(x => x.CreateDate, config => config.Ignore())
;
CreateMap<ChildClassView, ChildClass>()
.EqualityComparison((m, v) => m.Id == v.Id)
.ForMember(x => x.CreateDate, config => config.Ignore())
;
//automapper configuration
services.AddAutoMapper(c =>
{
c.AddCollectionMappers();
},typeof(TestClassProfile).Assembly);
So now I write a unit test to verify that the CreateDate
is ignored, but I get different results for the ChildClass.CreateDate
when I map directly from ChildClassView
-> ChildClass
than when I map the TestClassView
-> TestClass
.
This test passes:
var target1 = new ChildClass
{
CreateDate = new DateTime(2022, 1, 1)
};
var source1 = new ChildClassView
{
// no create date set
};
Mapper.Map(source1, target1);
//works
target1.CreateDate.Should().Be(new DateTime(2022, 1, 1));
This does not:
var target2 = new TestClass
{
ChildClasses = new()
{
new ChildClass
{
Id = 1,
CreateDate = new DateTime(2022, 1, 1)
}
}
};
var source2 = new TestClassView
{
ChildClasses = new()
{
new ChildClassView
{
Id = 1,
// no create date set
}
}
};
Mapper.Map(source2, target2);
//doesn't work. CreateDate is DateTime.MinValue.
target2.ChildClasses.First().CreateDate.Should().Be(new DateTime(2022, 1, 1));
Why does it seem like Automapper is ignoring my config value in the second example? How do I get it to respect the mapping for my child class when mapping the parent class? I tried to explictly state where the mapping for ChildClasses
should come from, but got the same result.
I tried making ChildClass
as a singular property under TestClass
, and that properly mapped. It's only when mapping a collection that it's wrong.
UPDATE: I tried using the answer from this question as suggested in the comments, but i'm still getting the same result. See above where I added the AddCollectionMappers() and the EqualityComparison specification to my child type.