これは、この回答の期限切れのリンクからの情報です:https ://stackoverflow.com/a/8923063/2005596
AutoMapper(http://automapper.codeplex.com)を使用する場合、複数のエンティティを1つのエンティティにマップする必要があるシナリオがよくあります。通常、これは、多数のドメインエンティティから単一のビューモデル(ASP.NET MVC)にマッピングするときに発生します。残念ながら、AutoMapper APIは、複数のエンティティを1つのエンティティにマップする機能を公開していません。ただし、これを行うためのヘルパーメソッドを作成するのは比較的簡単です。以下に、私が取ったアプローチを説明します。
この例では、ドメインモデルに次のエンティティがあります
public class Person
{
public int Id { get; set; }
public string Firstname { get; set; }
public string Surname { get; set; }
}
public class Address
{
public int Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string Country { get; set; }
}
public class Comment
{
public string Text { get; set; }
public DateTime Created { get; set; }
}
これに加えて、(ASP.NET MVCを使用して)1つのページにその人の詳細をその人の住所と関連するコメントを表示する必要があります。これを実装するために、以下に示すビューモデルを作成しました。これには、上記の3つのドメインエンティティすべてからのデータが含まれています。
public class PersonViewModel
{
public int Id { get; set; }
[DisplayName("Firstname")]
public string Firstname { get; set; }
[DisplayName("Surname")]
public string Surname { get; set; }
[DisplayName("Address Line 1")]
public string AddressLine1 { get; set; }
[DisplayName("Address Line 2")]
public string AddressLine2 { get; set; }
[DisplayName("Country Of Residence")]
public string Country { get; set; }
[DisplayName("Admin Comment")]
public string Comment { get; set; }
}
コントローラアクションメソッドでは、必要なエンティティを取得するためにドメインレイヤーに3つの個別の呼び出しを行いますが、これでも、複数のソースエンティティを単一の宛先エンティティにマップする必要があるという問題が残ります。このマッピングを実行するために、AutoMapperをカプセル化し、複数のソースオブジェクトを1つの宛先オブジェクトにマッピングできる機能を公開するヘルパークラスを作成しました。このクラスを以下に示します
public static class EntityMapper
{
public static T Map<T>(params object[] sources) where T : class
{
if (!sources.Any())
{
return default(T);
}
var initialSource = sources[0];
var mappingResult = Map<T>(initialSource);
// Now map the remaining source objects
if (sources.Count() > 1)
{
Map(mappingResult, sources.Skip(1).ToArray());
}
return mappingResult;
}
private static void Map(object destination, params object[] sources)
{
if (!sources.Any())
{
return;
}
var destinationType = destination.GetType();
foreach (var source in sources)
{
var sourceType = source.GetType();
Mapper.Map(source, destination, sourceType, destinationType);
}
}
private static T Map<T>(object source) where T : class
{
var destinationType = typeof(T);
var sourceType = source.GetType();
var mappingResult = Mapper.Map(source, sourceType, destinationType);
return mappingResult as T;
}
}
複数のソースオブジェクトを1つの宛先にマップするために、AutoMapperが提供する機能を利用して、ソースオブジェクトと既存の宛先オブジェクトの間のマッピングを実行できるようにしました。
最後に、3つのエンティティを取得し、単一のビューモデルへのマッピングを実行するコントローラーからのコードを以下に示します。
public ActionResult Index()
{
// Retrieve the person, address and comment entities and
// map them on to a person view model entity
var personId = 23;
var person = _personTasks.GetPerson(personId);
var address = _personTasks.GetAddress(personId);
var comment = _personTasks.GetComment(personId);
var personViewModel = EntityMapper.Map<PersonViewModel>(person, address, comment);
return this.View(personViewModel);
}