4

オブジェクトの2つのリスト間でマップしようとしています。ソースタイプには、タイプの複雑なプロパティがありAます。デスティネーションタイプは、タイプのフラット化されたサブセットとA、ソースタイプにある追加のスカラープロパティです。

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Source
{
    public A MyA { get; set; }
    public int SomeOtherValue { get; set; }
}

public class Destination
{
    public string Name { get; set; }
    public int SomeOtherValue { get; set; }
}

Source.MyA.Nameはっきりしない場合は、にマップして、にマップしDestination.NameたいSource.SomeOtherValueと思いDestination.SomeOtherValueます。

実際には、typeAには12ほどのプロパティがあり、その約80%が。の同じ名前のプロパティにマップされますDestinationCreateMap次のようにマッピングを明示的に記述すれば、物事を機能させることができます。

CreateMap<Source, Destination>()
    .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.MyA.Name));

ここでの欠点は、にコピーする必要があるの各プロパティForMemberに行を追加する必要がないことです。私は次のようなことができることを望んでいました:ADestination

CreateMap<Source, Destination>()
    .ForMember(dest => dest, opt => opt.MapFrom(src => src.MyA));

しかし、上記を試してみると、マッピングの登録時に実行時エラーが発生します。「メンバーのカスタム構成は、タイプの最上位の個々のメンバーに対してのみサポートされます。」

ありがとう

4

3 に答える 3

5

Aとの間のマッピングを作成しDestination、次に最初のマッピングを2番目に使用するために使用しますSourceDestinationAfterMap()

Mapper.CreateMap<A, Destination>();
Mapper.CreateMap<Source, Destination>()
      .AfterMap((s, d) => Mapper.Map<A, Destination>(s.MyA, d));

次に、次のように使用します。

var res = Mapper.Map<Source, Destination>(new Source { SomeOtherValue = 7,  MyA = new A { Id = 1, Name = "SomeName" } });
于 2012-11-01T00:16:13.470 に答える
0

回避策として、宛先の型に追加のプロパティを指定してカスタム型コンバーターを使用して、再帰を回避できます。

[TestFixture]
public class MapComplexType
{
    [Test]
    public void Map()
    {
        Mapper.CreateMap<A, Destination>();

        Mapper.CreateMap<Source, Destination>().ConvertUsing(new TypeConvertor());
        var source = new Source
                         {
                             MyA = new A
                                       {
                                           Name = "Name"
                                       },
                                       SomeOtherValue = 5
                         };
        var dest = new Destination();
        Mapper.Map(source, dest);
        Assert.AreEqual(dest.Name, "Name");
    }
}

public class TypeConvertor : ITypeConverter<Source, Destination>
{
    public Destination Convert(ResolutionContext context)
    {
        var destination = (Destination) context.DestinationValue;
        if (!((Destination)context.DestinationValue).IsMapped || destination == null)
        {
            destination = destination ?? new Destination();
            destination.IsMapped = true; // To avoid recursion
            Mapper.Map((Source)context.SourceValue, destination);
                            destination.IsMapped = false; // If you want to map the same object few times
        }
        Mapper.Map(((Source)context.SourceValue).MyA, destination);
        return (Destination)context.DestinationValue;
    }
}

public class A
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Source
{
    public A MyA { get; set; }
    public int SomeOtherValue { get; set; }
}

public class Destination
{
    public string Name { get; set; }
    public int SomeOtherValue { get; set; }
    // Used only for mapping purposes
    internal bool IsMapped { get; set; }
}
于 2012-10-29T22:21:34.103 に答える
0

これを試して、

Mapper.CreateMap<A, Destination>();
Mapper.CreateMap<Source, Destination>()
    .ForMember(destination => destination.Name, options => options.MapFrom(source => Mapper.Map<A, Destination>(source.MyA).Name));

var objSource = new Source { SomeOtherValue = 7, MyA = new A { Id = 1, Name = "SomeName" } };
var result = Mapper.Map<Source, Destination>(objSource);
于 2012-11-13T05:46:26.850 に答える