Elisabeth
Elisabeth

Reputation: 21206

Map a hierarchy object with AutoMapper

How can I map a c# class called Unit which has again a List<Unit>.

The concrete scenario is a rootUnit object which contains a List which are the first level children.

The first level children unit objects will not contain any other units so there will be no recursion in the hierarchy.

public class Unit
    {
        public Unit()
        {
            // Explicitly set the default value for the first unit in a hierarchy
            HierarchyIndex = 0;
            Units = new List<Unit>();
        }

        public List<Unit> Units { get; set; }

        public int UnitId { get; set; }
        public string Name { get; set; }       
        public Nullable<int> ParentId { get; set; }
        public int TemplateId { get; set; }       
        public bool HasChildren { get; set; }
        public bool IsFolder { get; set; }
        public DateTime CreatedAt { get; set; }
        public int HierarchyIndex { get; set; }
    }

Map the unit above to this viewmodel:

public class UnitTreeViewModel
{
    [JsonProperty("key")]
    public int UnitId { get; set; }
    [JsonProperty("title")]
    public string Name { get; set; }
    [JsonProperty("isLazy")]
    public bool HasChildren { get; set; } 
    [JsonProperty("isFolder")]
    public bool IsFolder { get; set; } 
}

Upvotes: 1

Views: 3481

Answers (1)

Mightymuke
Mightymuke

Reputation: 5144

Assuming the answer to my question in the comment above is yes, then you'll need to apply the mapping several times - similar to this question: AutoMapper and flattening nested arrays

Something like this might work:

AutoMapperConfigurator.cs

namespace StackOverflow.ListUnit
{
    using AutoMapper;

    public class MyProfile : Profile
    {
        public override string ProfileName
        {
            get
            {
                return "MyProfile";
            }
        }

        protected override void Configure()
        {
            Mapper.CreateMap<Unit, UnitTreeViewModel>();
        }
    }
}

MappingTests.cs

namespace StackOverflow.ListUnit
{
    using System.Collections.Generic;
    using System.Linq;

    using AutoMapper;

    using NUnit.Framework;

    [TestFixture]
    public class MappingTests
    {
        [Test]
        public void AutoMapper_Configuration_IsValid()
        {
            Mapper.Initialize(m => m.AddProfile<MyProfile>());
            Mapper.AssertConfigurationIsValid();
        }

        [Test]
        public void AutoMapper_Mapping_IsValid()
        {
            Mapper.Initialize(m => m.AddProfile<MyProfile>());
            Mapper.AssertConfigurationIsValid();

            var unit = new Unit
                {
                    UnitId = 123,
                    Name = "Stack Overflow Rocks",
                    HasChildren = true,
                    IsFolder = true,
                    Units =
                        new List<Unit>
                            {
                                new Unit
                                    {
                                        UnitId = 123123,
                                        Name = "I'm the first baby",
                                        HasChildren = false,
                                        IsFolder = false,
                                    },
                                new Unit
                                    {
                                        UnitId = 123321,
                                        Name = "I'm the second baby",
                                        HasChildren = false,
                                        IsFolder = false,
                                    }
                            }
                };

            var unitViewModels = new List<UnitTreeViewModel>
                {
                    Mapper.Map<Unit, UnitTreeViewModel>(unit)
                };
            unitViewModels.AddRange(
                unit.Units.Select(Mapper.Map<Unit, UnitTreeViewModel>));

            Assert.That(unitViewModels, Is.Not.Null);
            Assert.That(unitViewModels.Count(), Is.EqualTo(3));
            var unitViewModel = unitViewModels.First(x => x.UnitId == 123);
            Assert.That(unitViewModel, Is.Not.Null);
            Assert.That(unitViewModel.Name, Is.EqualTo("Stack Overflow Rocks"));
            unitViewModel = unitViewModels.First(x => x.UnitId == 123123);
            Assert.That(unitViewModel, Is.Not.Null);
            Assert.That(unitViewModel.Name, Is.EqualTo("I'm the first baby"));
            unitViewModel = unitViewModels.First(x => x.UnitId == 123321);
            Assert.That(unitViewModel, Is.Not.Null);
            Assert.That(unitViewModel.Name, Is.EqualTo("I'm the second baby"));
        }
    }
}

Upvotes: 2

Related Questions