Ich habe ein klasse:
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
}
Ich habe zwei Instanzen von Person (Person1 und Person2). Ich möchte den Inhalt von person2 nach person1 kopieren. Ich möchte diese Kopie in einer Anweisung erstellen und nicht Eigenschaft für Eigenschaft:
person1.LastName = person2.LastName;
Im Dokument wird ein Objekt in ein anderes Objekt kopiert, der Typ ist jedoch unterschiedlich. Wie kann ich das Objekt kopieren, wenn der Typ identisch ist?
c#
automapper
Kris-I
quelle
quelle
Antworten:
Soweit ich die Frage verstehe, möchte OP person2 nicht in eine neue Instanz von Person klonen , sondern fragt, wie der Inhalt von person2 in eine bereits vorhandene Instanz ( person1 ) von Person kopiert werden soll . Es gibt eine Überladung der Mapper.Map-Methode von AutoMapper, die dies für Sie erledigt:
Mapper.CreateMap<Person, Person>(); Mapper.Map<Person, Person>(person2, person1); //This copies member content from person2 into the _existing_ person1 instance.
Anmerkung 1: Die Antwort von @ alexl erstellt eine neue Instanz von Person . Wenn Sie andere Verweise auf die Instanz haben, auf die person1 verweist, erhalten diese nicht die (vermutlich) gewünschte Datenaktualisierung, wenn Sie die Variable person1 auf eine neue Instanz umleiten .
Hinweis 2: Sie müssen sich bewusst sein, dass die (rekursive) Kopiertiefe davon abhängt, welche Zuordnungen AutoMapper zum Zeitpunkt der Zuordnung kennt!
Wenn ein Mitglied der Person Klasse sagen , die Klasse ist Gehirn , und Sie haben zusätzlich getan
Mapper.CreateMap<Brain, Brain>();
vor dem Kopieren von DatenMapper.Map<Person, Person>(person2, person1);
Anruf, dann person1 ihren gegenwärtigen halten Gehirn Instanz aber das Gehirn wird die Mitgliedswerte erhalten person2 ‚s Gehirn - Instanz. Das heißt, Sie haben eine tiefe Kopie .Wenn AutoMapper jedoch vor dem Kopieren keine Brain-Brain-Zuordnung hat, ist das Gehirn von person1Das Mitglied verweist auf dieselbe Brain- Instanz wie die Person2 . Das heißt, Sie erhalten eine flache Kopie .
Dies gilt rekursiv für alle Mitglieder. Stellen Sie daher sicher, dass AutoMapper Zuordnungen für Mitgliedsklassen enthält, die Sie tief kopieren möchten, und keine Zuordnungen für Mitgliedsklassen, die Sie flach kopieren möchten.
Eine Alternative zur Verwendung von AutoMapper wäre die Verwendung eines Ansatzes mit Reflexion . (Beachten Sie, dass der Code im Link eine flache Kopie erstellt!)
"Unterstützung für das Füllen eines vorhandenen Objekts, anstatt dass AutoMapper das Zielobjekt selbst erstellt" wurde in AutoMapper Version 0.2 hinzugefügt .
quelle
Da Sie gefragt haben,
With Automapper?
kann ich vorschlagen, dass Sie AutoMapper nicht verwenden?Verwenden Sie stattdessen
MemberwiseClone()
in einerClone
Methode, zpublic class Person { public string FirstName { get; set; } public string LastName { get; set; } public Person Clone() { return (Person) MemberwiseClone(); } }
AKTUALISIEREN
Es ist wichtig zu beachten, dass dies nicht den Wunsch der Originalplakate erfüllt, in die kopiert
person1
werden sollperson2
Die Verwendung (und wie @Jimmy Bogard betont)
MemberwiseClone()
wird jedoch bevorzugt, wenn Sie nur eine Kopie (Klon) des Objekts erstellen müssen .Zum Beispiel, wenn Sie dies tun:
//I need a copy of person1 please! I'll make a new person object //and automapper everything into it! var person2 = new Person2(); Mapper.Map<Person, Person>(person1, person2)
dann solltest / könntest du wirklich gebrauchen
//oh wait, i can just use this! var person2 = person1.Clone()
quelle
return (Person) MemberwiseClone();
für eine schlechte Praxis oder einfach für einen "Code-Geruch" hält?Mapper.CreateMap<Person, Person>(); // Perform mapping var person1 = Mapper.Map<Person, Person>(person2);
Hoffe das hilft.
quelle
Mapper.Map<Person, Person>(person2, person1);
? Ihr Weg wird ein neues Objekt erstellenperson1
(für das ich in meiner Antwort getötet werde;))Warum möchten Sie dafür Automapper verwenden? Ein einfacher Klon würde die Arbeit für Sie erledigen.
Lesen Sie hier mehr: Deep Cloning von Objekten
quelle
In der aktuellen Version von AutoMapper können Sie die statische
AutoMapper.Mapper.Map
Methode nicht verwenden . Initialisieren Sie stattdessen einen neuen Mapper wie folgt:var config = new MapperConfiguration(cfg => { cfg.CreateMap<Person, Person>(); }); var mapper = new Mapper(config); var clone = mapper.Map<Person>(person);
Normalerweise möchten Sie den Mapper in der
Startup.cs
Datei für die Abhängigkeitsinjektion registrieren und in Ihre Business Class einfügen:public void ConfigureServices(IServiceCollection services) { var config = new MapperConfiguration(cfg => { cfg.CreateMap<Person, Person>(); }); var mapper = new Mapper(config); services.AddSingleton(mapper); // ... }
Wichtig: Erstellen oder injizieren Sie den Mapper nicht in Ihrer Entitätsklasse!
Natürlich sollten Sie es vorziehen,
MemberwiseClone()
in einfachen Fällen zu verwenden.quelle