値をコピーするコード
それでは、取得したデータを表示用のクラスにコピーしてみましょう。以下のコードではAuthorクラスを内包するBookクラスから、フラットなBookViewクラスへ詰め替えを行っています。
BookからBookViewへ詰め替え
public ActionResult Details(int id)
{
//LINQ to SQLでBookエンティティを取得
MyDbDataContext db = new MyDbDataContext();
Book book = (from b in db.Book where b.ID == id select b).First();
//(1)BookからBookViewへのマッピング方法を設定
Mapper.CreateMap<Book, BookView>();
//(2)BookからBookViewへの詰め替えを実施
BookView bookView = Mapper.Map<Book, BookView>(book);
return View(bookView);
}
詰め替えの手順は、以下の通りです。
Mapperクラス(AutoMapper名前空間)のCreateMap<コピー元の型,コピー先の型>メソッド呼び出します。CreateMapメソッドでは、様々なマッピングの方法を指定できますが、ここではクラス名のみ指定しています。
次にMap<コピー元の型,コピー先の型>メソッドを呼び出します。Mapメソッドを呼び出すとデータのコピーが行われます。引数にはコピー元のインスタンスを指定し、戻り値としてコピー結果のインスタンスを取得できます。
確認のために、次のデバッグ用のコードを記述しました。出力ウィンドウにて正しく詰め替えが行われていることを確認できます。
確認用のコードと実行結果(結果は見やすいように整形)
//コピーが正しいかを確認するデバッグ用コード
Debug.WriteLine("▼コピー元(BookとAuthor)");
Debug.WriteLine(book.ID);
Debug.WriteLine(book.Name);
Debug.WriteLine(book.Price);
Debug.WriteLine(book.Pubdate);
Debug.WriteLine(book.Author.Age);
Debug.WriteLine(book.Author.LastName);
Debug.WriteLine(book.Author.FirstName);
Debug.WriteLine("▼コピー先(BookView)");
Debug.WriteLine(bookView.ID);
Debug.WriteLine(bookView.Name);
Debug.WriteLine(bookView.Price);
Debug.WriteLine(bookView.Pubdate);
Debug.WriteLine(bookView.AuthorAge);
Debug.WriteLine(bookView.AuthorLastName);
Debug.WriteLine(bookView.AuthorFirstName);
//↓デバッグコードの出力結果
// ▼コピー元(BookとAuthor)
// 1 初めてのC# 2980 2008/12/24 0:00:00 28 中田 一郎
// ▼コピー先(BookView)
// 1 初めてのC# 2980 2008/12/24 0:00:00 28 中田 一郎
このようにAutoMapperは、名前が一致するプロパティがあれば自動的に値をコピーします。AuthorプロパティのAgeプロパティのようにネストする場合であっても、アルファベットの大文字を使ってクラスとプロパティを識別できます。ここでは、コピー先のプロパティ名を「AuthorAge」と命名することでコピーしています。もし「Authorage」という名前ではコピーされませんので注意してください。
ASP.NET MVCでの確認
ASP.NET MVCでは、ページを生成するウィザードが用意されています。
今回のようにViewModelを作成することによって、DBモデルとプレゼンテーションモデルを明確に分離してデータを管理することができます。