古いマッピング標準からオートマッパーに変換するのにかなりの時間がかかります。
これが私のクラスです
// Models
public class BaseModel
{
public Int64 Id { get; set; }
public Guid UniqueId { get; set; }
public DateTime? CreateDate { get; set; }
public DateTime? LastUpdate { get; set; }
}
public class LibraryItemModel : BaseModel
{
public string Name { get; set; }
public string Description { get; set; }
public string URL { get; set; }
public bool IsActive { get; set; }
public List<LibraryCategoryModel> Categories { get; set; }
}
public class LibraryCategoryModel : BaseModel
{
public string Description { get; set; }
}
// Entity Classes
public partial class LibraryItem
{
public LibraryItem()
{
this.LibraryItemCategories = new HashSet<LibraryItemCategory>();
}
public long Id { get; set; }
public System.Guid UniqueId { get; set; }
public string Description { get; set; }
public string URL { get; set; }
public System.DateTime CreateDate { get; set; }
public System.DateTime LastUpdate { get; set; }
public bool IsActive { get; set; }
public string Name { get; set; }
public virtual ICollection<LibraryItemCategory> LibraryItemCategories { get; set; }
}
// comes from a ternary table in DB... many to many
public partial class LibraryItemCategory
{
public long LibraryItemId { get; set; }
public long LibraryCategoryId { get; set; }
public System.DateTime CreateDate { get; set; }
public System.DateTime LastUpdate { get; set; }
public virtual LibraryCategory LibraryCategory { get; set; }
public virtual LibraryItem LibraryItem { get; set; }
}
public partial class LibraryCategory
{
public LibraryCategory()
{
this.LibraryCategoryRoles = new HashSet<LibraryCategoryRole>();
this.LibraryItemCategories = new HashSet<LibraryItemCategory>();
}
public long id { get; set; }
public System.Guid UniqueId { get; set; }
public string Description { get; set; }
public System.DateTime CreateDate { get; set; }
public System.DateTime LastUpdate { get; set; }
public virtual ICollection<LibraryCategoryRole> LibraryCategoryRoles { get; set; }
public virtual ICollection<LibraryItemCategory> LibraryItemCategories { get; set; }
}
// Old Conversion code doing it the long way
private LibraryItemModel Convert(Entities.LibraryItem libraryItem)
{
var newLibraryItem = new LibraryItemModel
{
UniqueId = libraryItem.UniqueId,
Name = libraryItem.Name,
Description = libraryItem.Description,
URL = libraryItem.URL,
CreateDate = libraryItem.CreateDate,
LastUpdate = libraryItem.LastUpdate,
IsActive = libraryItem.IsActive,
Categories = new List<LibraryCategoryModel>()
};
foreach (var lc in libraryItem.LibraryItemCategories)
{
var newCategory = new LibraryCategoryModel
{
UniqueId = lc.LibraryCategory.UniqueId,
Description = lc.LibraryCategory.Description,
CreateDate = lc.LibraryCategory.CreateDate,
LastUpdate = lc.LibraryCategory.LastUpdate
};
newLibraryItem.Categories.Add(newCategory);
}
return newLibraryItem;
}
// My attempt at automapper to go between the models and entities
Mapper.CreateMap<EF.Entities.LibraryItem, LibraryItemModel>();
Mapper.CreateMap<LibraryItemModel, EF.Entities.LibraryItem>();
.ForMember(lim => lim.LibraryItemCategories, o => o.Ignore()
Mapper.CreateMap<EF.Entities.LibraryCategory, LibraryCategoryModel>();
Mapper.CreateMap<LibraryCategoryModel, EF.Entities.LibraryCategory>()
.ForMember(lcm => lcm.LibraryCategoryRoles, o => o.Ignore())
.ForMember(lcm => lcm.LibraryItemCategories, o => o.Ignore());
無視やカスタムマッピングをどのように構成しても、このネストは気に入らないようです。このような複雑なオブジェクトとのマッピングをどのように行うことができるかを教えてくれるAutomapperの専門家なら誰でも。エンティティクラスは、EF6edmxファイルを介して生成されています。
したがって、基本的にここでの問題は、LibraryItemCategory
に属する各LibraryItem
から、各LibraryCategoryModel
のLibraryItemCatalog
プロパティのプロパティを含むLibraryCatalog
にマップすることです。
まず、コレクションを相互に正しくマップする必要があります。
Mapper.CreateMap<LibraryItem, LibraryItemModel>()
.ForMember(
dest => dest.Categories,
opt => opt.MapFrom(src => src.LibraryItemCategories));
次に、LibraryItem.LibraryItemCategories
内の各LibraryItemCategory
をLibraryCatalogModel
にマッピングすることについて心配する必要があります。問題で述べたように、各LibraryItemCategory
のLibraryCatalog
プロパティにアクセスし、代わりに実際にそこからマップする必要があります。これがどのように見えるか:
Mapper.CreateMap<LibraryItemCategory, LibraryCategoryModel>()
.ConstructUsing(ct => Mapper.Map<LibraryCategoryModel>(ct.LibraryCategory))
.ForAllMembers(opt => opt.Ignore());
ここでは、AutoMapperにLibraryItemCategory
からLibraryCategoryModel
にマップするには、内部のLibraryCategoryModel
プロパティでMapper.Map
を呼び出すanotherを使用してLibraryCategory
を作成する必要があることを伝えています。
次に、あとはLibraryCategory
からLibraryCategoryModel
へのマッピングを定義するだけです。
Mapper.CreateMap<LibraryCategory, LibraryCategoryModel>();
これで、LibraryItem
のMapper.Map
を呼び出すと、すべてが処理されます。
または、マップをLibraryItemCategory
からLibraryCategoryModel
に削除し、LINQを使用して、LibraryCategory
からLibraryItem
へのマッピング定義で実際にマップするLibraryItemModel
sのコレクションを作成することもできます。
Mapper.CreateMap<LibraryItem, LibraryItemModel>()
.ForMember(
dest => dest.Categories,
opt => opt.MapFrom(
src => src.LibraryItemCategories.Select(lb => lb.LibraryCategory)));
明らかに、LibraryCategory
からLibraryCategoryViewModel
へのマッピングが必要ですが、マッピングが少ないため、これをお勧めします。
次のようなものを試してください
Mapper
.CreateMap<LibraryItemModel, EF.Entities.LibraryItem>()
.ForMember(
dest => dest.LibraryItemCategories,
opt => opt.MapFrom(src => src.LibraryItemCategories )
);
したがって、ネストされたプロパティがマップされる場所を宣言します。
ドキュメントサイト で別の例を見つけることができます