1

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; } 
}
Elisabeth
  • 20,496
  • 52
  • 200
  • 321
  • Do you need many `UnitTreeViewModel` for each `Unit`? (ie, one for the parent, and one each for the list items?) – Mightymuke Nov 25 '12 at 22:32

1 Answers1

2

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"));
        }
    }
}
Community
  • 1
  • 1
Mightymuke
  • 5,094
  • 2
  • 31
  • 42
  • This is funny. I used the default mapping (Mapper.CreateMap(); ) that I had before. Did not thought that would work. But it did. Thanks for the idea. – Elisabeth Nov 27 '12 at 12:13