Wie AutoMapper verwenden, um anzeigen Ziel-Objekts mit einem untergeordneten Objekt in der Quell-Objekt?
Ich habe die Quell-und Ziel-Objekte wie diese:
class ProductWithCategories //Source class
{
public Product Product { get; set; } //Product is an EF entity class
public IEnumerable<Category> Categories { get; set; }
}
class ProductViewModel //Dest class
{
public int Id { get; set; }
//Other properties with the same name as Product class
public IEnumerable<CategoryViewModel> Categories { get; set; }
}
So, mein Bedarf ist die Karte die Werte von source.Product
in dest
, und dann source.Categories
in dest.Categories
. Ist es möglich mit AutoMapper?
Ich habe versucht, und ich war nicht überrascht, wenn es versagt:
config.CreateMap<ProductWithCategories, ProductViewModel>()
.ForMember(q => q, option => option.MapFrom(q => q.Product))
.ForMember(q => q.Categories, option => option.MapFrom(q => q.Categories));
Hier ist die Ausnahme, die ich erhielt:
[AutoMapperConfigurationException: Benutzerdefinierte Konfiguration für die Mitglieder ist
unterstützt werden nur für top-level die einzelnen Mitglieder auf einen Typ.]
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nach einiger Diskussion mit der OP, es stellt sich heraus sein Haupt benötigen, um schnell ordnen Sie ein Kind/geschachtelte Objekt in dem Quellobjekt, um die abgeflachte Ziel-Objekt. Will er nicht schreiben, ein mapping für jede Eigenschaft des Ziels.
Hier ist ein Weg, dies zu erreichen:
Product
->ProductViewModel
verwendet, um glätten die Mitglieder des ProduktesCategory
zuCategoryViewModel
Mapping definieren
ProductWithCategories
->ProductViewModel
dass Karten der Kategorien, und klicken Sie dann in der aftermap, Karte derProduct
:config.CreateMap<ProductWithCategories, ProductViewModel>()
.ForMember(q => q.Id, option => option.Ignore()) //flattened in AfterMap
.ForMember(q => q.Categories, option => option.MapFrom(q => q.Categories))
.AfterMap((src, dst) => Mapper.Map(src.Product, dst));
Mapper
.Unter Verwendung Aktueller Versionen von AutoMapper, können Sie etwas wie die folgende:
ConstructUsing() wird verwendet, um zu erzeugen, und füllen Sie die Basisklasse, von der verschachtelten Kind[ren] der Quelle. Wenn Sie mehr als eine solche geschachtelte Kind, würden Sie brauchen, um mehrere mapping-Aufrufe ordnen Sie jedem von Ihnen nacheinander auf die Instanz generiert, indem die erste Karte () - Aufruf. Die .ForAllOtherMembers() ist relativ neu (wenn Sie es nicht haben, Holen Sie sich eine neuere version von AutoMapper.) Leider ist es etwas unsicher, als ob Sie auf Ziel hinzufügen Mitglieder, die Notwendigkeit, Zuordnung, aber vergessen, um die Karte zu aktualisieren, Konfiguration Validierung wird nicht fangen.
.ConstructUsing((s, ctx) => ctx.Mapper.Map<ProductViewModel>(s.Product))
. Sie können den Zugriff auf die runtime-mapper auf die ResolutionContext.sollten Sie tun, wie -
Aber es ist besser, zu wickeln diese Eigenschaften von
ProductViewModel
(Requisiten wieId
), die innerhalb einer anderen Klasse. Und erstellen Sie eine andere Zuordnung für die Dinge zu arbeiten automapper Weg.TypeConverter
oderValueResolver
. Sie ermöglichen es, um zu Steuern, die Erstellung des Ziel-Objekts.Die betreffende Zeile, die den Fehler generiert wird
Die Fehlermeldung ist schwer zu verstehen, aber es bedeutet, dass Sie haben, um den Ziel-Eigenschaften explizit:
Haben Sie auch eine Zuordnung zu definieren, von
Category
zuCategoryViewModel
fürarbeiten:
Product
es töten AutoMapper Zweck.Product
undProductViewModel
und anzeigen der Kategorien inAfterMap
.