Let's assume I have three classes that are subclasses of a base class:
public class BaseClass
{
public string BaseName { get; set; }
}
public class Subclass1 : BaseClass
{
public string SubName1 { get; set; }
}
public class Subclass2 : BaseClass
{
public string SubName2 { get; set; }
}
public class Subclass3 : BaseClass
{
public string SubName3 { get; set; }
}
I would like to map these to a ViewModel class that looks like this:
public class ViewModel
{
public string BaseName { get; set; }
public string SubName1 { get; set; }
public string SubName2 { get; set; }
public string SubName3 { get; set; }
}
ViewModel
simply combines the properties on all of the subclasses and flattens it. I tried to configure the mapping like so:
AutoMapper.CreateMap<BaseClass, ViewModel>();
Then I tried grabbing data from my database like so:
var items = Repo.GetAll<BaseClass>();
AutoMapper.Map(items, new List<ViewModel>());
However, what ends up happening is that only the BaseName
property will be populated in the ViewModel
. How would I configure AutoMapper so that it will map the properties in the subclasses as well?
Alternatively, AutoMapper supports convention based mapping of enum values in a separate package AutoMapper.
How AutoMapper works? AutoMapper internally uses a great concept of programming called Reflection. Reflection in C# is used to retrieve metadata on types at runtime. With the help of Reflection, we can dynamically get a type of existing objects and invoke its methods or access its fields and properties.
There appears to be a bug or limitation in AutoMapper that you need corresponding TSource and TDestination hierarchies. Given:
public class BaseClass {
public string BaseName { get; set; }
}
public class Subclass1 : BaseClass {
public string SubName1 { get; set; }
}
You need the following view models:
public class ViewModel {
public string BaseName { get; set; }
}
public class ViewModel1 : ViewModel {
public string SubName1 { get; set; }
}
The following code then works:
Mapper.CreateMap<BaseClass, ViewModel>()
.Include<Subclass1, ViewModel1>();
Mapper.CreateMap<Subclass1, ViewModel1>();
var items = new List<BaseClass> {new Subclass1 {BaseName = "Base", SubName1 = "Sub1"}};
var viewModels = Mapper.Map(items, new List<ViewModel>());
Try this:
AutoMapper.CreateMap<BaseClass, ViewModel>()
.Include<Subclass1, ViewModel>()
.Include<Subclass2, ViewModel>()
.Include<Subclass3, ViewModel>();
AutoMapper.CreateMap<Subclass1, ViewModel>();
AutoMapper.CreateMap<Subclass2, ViewModel>();
AutoMapper.CreateMap<Subclass3, ViewModel>();
var items = Repo.GetAll<BaseClass>();
AutoMapper.Map(items, new List<ViewModel>());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With