简体   繁体   中英

Automapper what is the best way to configure mapping profile for a simple child parent structure

I have the following POCO

Public Class SamplePOCO{
    Public String Id;
    Public String FromSamplePocoId;
    Public String ToSamplePocoId;
}

and the following model

Public Class SampleObject{
    Public String Id;
    Public SampleObject FromSampleObject;
    Public SampleObject ToSampleObject;
}

I want to create a mapping profile on top of something similar to the following with AutoMapper. What is the best way to achieve this?

I would appreciate some help.

Edit

Please consider the following. Sorry for not being clear before.

Public Class POCOContainerClass{
    SamplePOCO[] SampleList
}

Public Class ObjectContainerClass{
    SampleObject[] SampleList
}

SamplePOCO samplePOCO1 = new()
{
    Id = "100",
    FromSamplePocoId = "200",
    ToSamplePocoId = "300",
};

SamplePOCO samplePOCO2 = new()
{
    Id = "200",
    FromSamplePocoId = "100",
    ToSamplePocoId = "300",
};

SamplePOCO samplePOCO3 = new()
{
    Id = "300",
    FromSamplePocoId = "200",
    ToSamplePocoId = "100",
};

SamplePOCO[] SamplePOCOList = new []{samplePOCO1 ,samplePOCO2 ,samplePOCO3 };

var samplePOCOContainer = new POCOContainerClass{SampleList = SamplePOCOList };

var sampleObjectContainer = _mapper.Map<ObjectContainerClass>(samplePOCOContainer);

Edit 2 (Sorry that it's in VB)

As you can see here, while mapping a SystemInfo to NetSystem, we first map the zones and save them in a collection, then we can use that collection to relate the nodes with that zone. This is possible because they are two different objects. In my case, I am trying to find a solution for self-referencing types. I hope it's a bit more clear now. I will try to edit for C# and simplify the coede later.

<System.Runtime.CompilerServices.Extension>
        Public Function GetZoneList(ctx As ResolutionContext) As Dictionary(Of String, NetZone)
            Dim zoneList As Dictionary(Of String, NetZone)
            If Not ctx.Options.Items.TryGetValue("zone", zoneList) Then
                zoneList = New Dictionary(Of String, NetZone)
                ctx.Options.Items.Add("zone", zoneList)
            End If
            Return zoneList
        End Function


Public Class CommonNetworkProfiles
    Inherits Profile
    Public Sub New()
CreateMap(Of NodeInfo, NetNode)().ForMember(Function(n) n.Zone, Sub(opt As IMemberConfigurationExpression(Of NodeInfo, NetNode, Object))
                                                                                opt.MapFrom(Of NetZone)(AddressOf MapZoneNamesToNetZoneObjects)
                                                                            End Sub).AfterMap(
            Sub(ni, nn, ctx)
                Dim nodeList = ctx.GetNodeList()
                If Not nodeList.ContainsKey(nn.UID) Then
                    nodeList.Add(nn.UID, nn)
                End If
            End Sub).ReverseMap().ForMember(Function(ni) ni.Name, Sub(opt) opt.MapFrom(Function(nn) nn.Zone.Name))

CreateMap(Of ZoneInfo, NetZone)().AfterMap(
            Sub(zi, nz, ctx)
                Dim zoneList = ctx.GetZoneList()
                If Not zoneList.ContainsKey(nz.Name) Then
                    zoneList.Add(nz.Name, nz)
                End If
            End Sub).ReverseMap()

CreateMap(Of SystemInfo, NetSystem)().ForMember(
        Function(dst) dst.Zones,
        Sub(opt As IMemberConfigurationExpression(Of SystemInfo, NetSystem, NetList(Of NetZone)))
            opt.MapFrom(Function(si, ns, m, ctx)
                            ns.Zones.AddRange(si.Zones.Select(AddressOf ctx.Mapper.Map(Of NetZone)).ToList)
                        End Function)
            opt.SetMappingOrder(2)
        End Sub).
        ReverseMap()


Private Shared Function MapZoneNamesToNetZoneObjects(ni As NodeInfo, nn As NetNode, member As Object, ctx As ResolutionContext) As NetZone
            Dim netZone As NetZone = Nothing
            Return If(ctx.GetZoneList().TryGetValue(ni.Name, netZone), netZone, Nothing)
        End Function
    End Sub
End Class

I will give you answer for C# but you can modify for vb.net.

First option is to add this to your profile to explicitly tell automapper how to map the properties:

public class MyProfile : Profile
{
    public MyProfile()
    {
        CreateMap<SampleObject, SamplePOCO>()
            .ForMember(dest => dest.FromSamplePocoId, opt => opt.MapFrom(src => src.FromSampleObject.Id))
            .ForMember(dest => dest.ToSamplePocoId, opt => opt.MapFrom(src => src.ToSampleObject.Id))
            .ReverseMap();

        CreateMap<POCOContainerClass, ObjectContainerClass>();
    }        
}

Second option is to rename FromSamplePocoId property to FromSampleObjectId and ToSamplePocoId to ToSampleObjectId . Automapper will be able to map automatically

  • SampleObject. FromSampleObject.Id to
  • SamplePOCO. FromSampleObjectId

(notice the property naming) without the extra profile configuration from first option.

https://docs.automapper.org/en/stable/Reverse-Mapping-and-Unflattening.html

Update:

SamplePOCO samplePOCO = new()
{
    Id = "100",
    FromSamplePocoId = "200",
    ToSamplePocoId = "300",
};

var sampleObject = _mapper.Map<SampleObject>(samplePOCO);

映射器

Update 2: I added CreateMap<POCOContainerClass, ObjectContainerClass>(); in the mapping profile. Your example code has this result:

SamplePOCO samplePOCO1 = new()
{
    Id = "100",
    FromSamplePocoId = "200",
    ToSamplePocoId = "300",
};

SamplePOCO samplePOCO2 = new()
{
    Id = "200",
    FromSamplePocoId = "100",
    ToSamplePocoId = "300",
};

SamplePOCO samplePOCO3 = new()
{
    Id = "300",
    FromSamplePocoId = "200",
    ToSamplePocoId = "100",
};

SamplePOCO[] SamplePOCOList = new []{samplePOCO1 ,samplePOCO2 ,samplePOCO3 };

var samplePOCOContainer = new POCOContainerClass{SampleList = SamplePOCOList };

var sampleObjectContainer = _mapper.Map<ObjectContainerClass>(samplePOCOContainer);

映射器2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM