1

注:AutoMapperメーリングリストでもこの質問をしました

私のMVCアプリケーションには、基本的に2つのレベルのマッピングがあります(この質問のために簡略化されています)。

RepositoryObject <-> Entity <-> ViewModel

2つのプロファイルを作成し、それぞれが適切なマッピングレベルの構成を処理します。

「RepositoryObjects」は最終的にXMLにシリアル化され、RESTWebサービスで使用されます。私たちが見つけた問題は、RepositoryObjectの空のコレクションがXMLの空の要素にシリアル化されることでした。これにより、Webサービスが要素を予期していないか、データを含む要素を予期しているため、問題が発生します。

AllowNullCollections構成設定を使用してこれを解決することができました。これにより、(もちろん)空のコレクションではなくnullコレクションが作成され、正常にシリアル化されます。

ただし、ジミーが指摘しているように、これは実際にはベストプラクティスではないため、これをグローバルな設定として使用することは完全には快適ではありません。RepositoryObject <-> EntityRepositoryObjectsは自動生成され(とにかく醜い)、アプリケーション内で非常に低レベルであるため、マッピングに含めることができてうれしいです。Entity <-> ViewModelしかし、可能であれば、マッピングを「破損」させたくないのです。

では、プロファイルごとにこの設定を構成することは可能ですか?

ありがとう。

アップデート

ここでテストコードを作成しました:https ://gist.github.com/4069909

参考のためにここにコピーしました:

ProfileClasses.cs

namespace NullCollectionIssue
{
    using System.Collections.Generic;

    public class SourceProfileOne
    {
        public ICollection<string> Stuff { get; set; }
    }

    public class DestProfileOne
    {
        public ICollection<string> Stuff { get; set; }
    }

    public class SourceProfileTwo
    {
        public ICollection<string> Stuff { get; set; }
    }

    public class DestProfileTwo
    {
        public ICollection<string> Stuff { get; set; }
    }
}

AutoMapperConfigurator.cs

namespace NullCollectionIssue
{
    using AutoMapper;

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

        protected override void Configure()
        {
            AllowNullCollections = true;
            Mapper.CreateMap<SourceProfileOne, DestProfileOne>();
        }
    }

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

        protected override void Configure()
        {
            Mapper.CreateMap<SourceProfileTwo, DestProfileTwo>();
        }
    }

    public static class AutoMapperConfigurator
    {
        public static void Configure()
        {
            Mapper.Initialize(x =>
            {
                x.AddProfile<ProfileOne>();
                x.AddProfile<ProfileTwo>();
            });
        }
    }
}

MappingTests.cs

namespace NullCollectionIssue
{
    using AutoMapper;

    using NUnit.Framework;

    [TestFixture]
    public class MappingTests
    {
        [Test]
        public void AutoMapper_Configuration_IsValid()
        {
            AutoMapperConfigurator.Configure();
            Mapper.AssertConfigurationIsValid();
        }

        [Test]
        public void AutoMapper_ProfileOne_AllowsNullCollections()
        {
            AutoMapperConfigurator.Configure();
            Mapper.AssertConfigurationIsValid();

            var source = new SourceProfileOne { Stuff = null };
            var dest = Mapper.Map<SourceProfileOne, DestProfileOne>(source);

            Assert.That(dest, Is.Not.Null);
            Assert.That(dest.Stuff, Is.Null);
        }

        [Test]
        public void AutoMapper_ProfileTwo_DoesntAllowNullCollections()
        {
            AutoMapperConfigurator.Configure();
            Mapper.AssertConfigurationIsValid();

            var source = new SourceProfileTwo { Stuff = null };
            var dest = Mapper.Map<SourceProfileTwo, DestProfileTwo>(source);

            Assert.That(dest, Is.Not.Null);
            Assert.That(dest.Stuff, Is.Not.Null);
            Assert.That(dest.Stuff, Is.Empty);
        }
    }
}

テストAutoMapper_Configuration_IsValidAutoMapper_ProfileTwo_DoesntAllowNullCollectionsて合格しますが、がnullでないAutoMapper_ProfileOne_AllowsNullCollectionsため、テストは失敗します。dest.Stuff

4

2 に答える 2

1

この機能の最初のコミットのソースコードを見ると、これはプロファイルプロパティであるように見えます-Profile.csを見てください。

だから、私はそれがプロファイルごとに機能するはずだと思います。私はそれを試しませんでした。

于 2012-11-10T13:35:38.067 に答える
1

Mapper.Mapconfigureメソッドでstaticを呼び出しているため、この動作が発生します。

protected override void Configure()
{
    Mapper.CreateMap<SourceProfileTwo, DestProfileTwo>();
}

代わりに

protected override void Configure()
{
    CreateMap<SourceProfileTwo, DestProfileTwo>();//leading Mapper. removed
}
于 2012-11-14T03:07:58.687 に答える