0

次のコードがあります。

[Test]
public void ConditionalMapping()
{
    var src = new Sample1 {Age = 1, Number = null};
    var dest = new Sample2 {Age = null, Number = 1};

    Hydrate(src, dest, false);

    Assert.That(dest.Age, Is.EqualTo(1));
    Assert.That(dest.Number, Is.EqualTo(1));

    src = new Sample1 {Age = null, Number = 1};
    dest = new Sample2 {Age = 1, Number = null};

    Hydrate(src, dest, true);

    Assert.That(dest.Age, Is.Null);
    Assert.That(dest.Number, Is.EqualTo(1));
}

public void Hydrate(Sample1 src, Sample2 dest, bool allowOverride)
{
    if (!dest.Age.HasValue || allowOverride)
        dest.Age = src.Age;

    if (!dest.Number.HasValue || allowOverride)
        dest.Number = src.Number;
}

public class Sample1
{
    public int? Age { get; set; }
    public int? Number { get; set; }
}

public class Sample2
{
    public int? Age { get; set; }
    public int? Number { get; set; }
}

これは基本的にint?、値がの場合nullを水和しallowOverride = true、フィールドの値をチェックせずに値を水和します。

Automapperでこれを行うにはどうすればよいですか?

ここに示すように .Condition() を使用できることを知っています。

Automapper の条件が無視される

しかし、次の方法がわかりませんでした。

  1. に基づいてロジックをint?1 つずつ定義せずに適用します。
  2. allowOverrideマッパーにブール値を含めます。
4

1 に答える 1

0

allowOverrideフラグをどのように機能させたいかによって、潜在的な解決策を見つけたかもしれません。

フラグをすべてのマッピングで同じように動作させたい場合は、次のように作成できTypeConverterます

public class NullableIntConverter : ITypeConverter<int?, int?>
{
    private bool AllowOverrides { get; set;}

    public NullableIntConverter(bool allowOverrides)
    {
        AllowOverrides = allowOverrides;
    }

    public int? Convert(ResolutionContext context)
    {
        var source = context.SourceValue as int?;
        var destination = context.DestinationValue as int?;
        if (destination.HasValue && !AllowOverrides)
            return destination;
        else
            return source;
    }
}

次のように初期化します。

Mapper.CreateMap<Sample1, Sample2>();
Mapper.CreateMap<int?, int?>().ConvertUsing(new NullableIntConverter(true));
Mapper.AssertConfigurationIsValid();

値の宛先をチェックし、コンストラクターの引数に応じて必要に応じてオーバーライドします。


また


マッピングごとに具体的に構成できるようにしたい場合は、を使用できますValueResolver(このコードは追加の検証を行うことができることに注意してください):

public class NullableIntResolver : IValueResolver
{
    public bool AllowOverrides { get; set; }

    public NullableIntResolver(bool allowOverrides)
    {
        AllowOverrides = allowOverrides;
    }

    public ResolutionResult Resolve(ResolutionResult source)
    {
        // Add validation for source and destination types
        return source.New(
                   ResolveCore((int?) source.Value,
                               DestinationMemberValue(source.Context)),
                   typeof(int?));
    }

    public int? ResolveCore(int? source, int? destination)
    {
        if (destination.HasValue && !AllowOverrides)
            return destination;
        else
            return source;
    }

    private int? DestinationMemberValue(ResolutionContext context)
    {
        var destObject = context.DestinationValue;
        var destMemberName = context.MemberName;
        return (int?) destObject
                          .GetType()
                          .GetProperty(destMemberName)
                          .GetValue(destObject, null);
    }
}

次に、次のようにマッピングを初期化できます。

var allowOverrides = true;
Mapper.CreateMap<Sample1, Sample2>()
    .ForMember(dest => dest.Age,
               opt => opt.ResolveUsing<NullableIntResolver>()
               .FromMember(src => src.Age)
               .ConstructedBy(() => new NullableIntResolver(allowOverrides)))
    .ForMember(dest => dest.Number,
               opt => opt.ResolveUsing<NullableIntResolver>()
               .FromMember(src => src.Number)
               .ConstructedBy(() => new NullableIntResolver(allowOverrides)));
Mapper.AssertConfigurationIsValid();
于 2013-04-18T03:28:53.233 に答える