Überspringen Sie Nullwerte mit benutzerdefinierter Konfliktlöser
Will ich mit automapper die Zuordnung zwischen meine öffentlichen Daten Verträge und meine DB-Modelle. Ich habe eine Klasse angelegt, die automatisch geht durch alle Verträge sind erstellt Zuordnungen. Das einzige problem das ich habe ist, dass ich nur wollen, um die anzeigen-Werte aus den Vertrag mit dem DB-Modell, wenn der Wert nicht null ist. Ich habe mir andere Frage auf, die hier aber nicht sehen-Beispiele für benutzerdefinierte Konfliktlöser.
Hier ist mein code
var mapToTarget = AutoMapper.Mapper.CreateMap(contract, mappedTo);
foreach (var property in contract.GetProperties().Where(property => property.CustomAttributes.Any(a => a.AttributeType == typeof(MapsToProperty))))
{
var attribute = property.GetCustomAttributes(typeof(MapsToProperty), true).FirstOrDefault() as MapsToProperty;
if (attribute == null) continue;
mapToTarget.ForMember(attribute.MappedToName,
opt =>
opt.ResolveUsing<ContractToSourceResolver>()
.ConstructedBy(() => new ContractToSourceResolver(new MapsToProperty(property.Name, attribute.SourceToContractMethod, attribute.ContractToSourceMethod))));
}
private class ContractToSourceResolver : ValueResolver<IDataContract, object>
{
private MapsToProperty Property { get; set; }
public ContractToSourceResolver(MapsToProperty property)
{
Property = property;
}
protected override object ResolveCore(IDataContract contract)
{
object result = null;
if (Property.ContractToSourceMethod != null)
{
var method = contract.GetType()
.GetMethod(Property.ContractToSourceMethod, BindingFlags.Public | BindingFlags.Static);
result = method != null ? method.Invoke(null, new object[] {contract}) : null;
}
else
{
var property =
contract.GetType().GetProperties().FirstOrDefault(p => p.Name == Property.MappedToName);
if (property != null)
{
result = property.GetValue(contract);
}
}
return result;
}
}
Und dies ist, wie ich es verwenden möchten
AutoMapper.Mapper.Map(dataContract, dbModel)
Diese derzeit funktioniert Super, aber wenn es einen NULL-Wert in den dataContract-dann wird es ersetzt den vorhandenen Wert in der dbModel, das ist nicht das, was ich will. Wie mache ich AutoMapper ignorieren null-Werte Quelle?
BEARBEITEN
Wie bereits in einer der Antworten gibt es in diesem
Mapper.CreateMap<SourceType, DestinationType>().ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));
Diese wäre ideal, außer der Tatsache, dass .ForAllMembers ist nicht zugänglich
Mapper.CreateMap(SourceType, DestinationType)
InformationsquelleAutor Mike Norgate | 2013-11-16
Du musst angemeldet sein, um einen Kommentar abzugeben.
UPDATE: IsSourceValueNull ist nicht verfügbar ab V5.
Wenn Sie möchten, dass alle Quell-Eigenschaften mit null-Werte werden ignoriert, die Sie nutzen könnten:
Sonst, Sie können tun, etwas ähnliches für jedes Mitglied.
Lesen diese.
Hi, können wir konfigurieren die Bedingung für alle Klassen automatisch? Danke.
Das ist eine gute Idee. Ich bin da nicht so sicher. Meine Vermutung, die Sie verwenden können, Reflexion und bekommen alle Klassen und foreach-Klasse, die Sie tun können, über Logik.
Dies funktioniert nicht AutoMapper 6.
Bin mit automapper 6.0.2. die Erweiterung IsSourceValueNull nicht vorhanden
InformationsquelleAutor Prasad Kanaparthi
Für neuere Versionen, nutzen Sie die API-Instanz verwenden, verwenden Sie diese statt:
Hinweis: Diese Funktion funktioniert wie der 5.0.2, brechen am späteren Versionen dieses Schreibens. Warten auf die nächste 5.2.x-Version wird empfohlen, wenn eine Aktualisierung von 5.0.2.
Ich fügte hinzu, eine Antwort, die funktioniert für mein Projekt, das mit AutoMapper 6.0.2.
InformationsquelleAutor Marc Lopez
Die Lösung hier funktioniert für mein Projekt, was ist mit AutoMapper 6.0.2. In früheren Projekten mit AutoMapper 4, die ich benutzt hatte IsSourceValueNull zu erreichen ein ähnliches Verhalten. Ich habe nullable-Typen zugeordnet, die zu non-nullable Typen in meinem Projekt, diese Lösung ist in der Lage, das Szenario.
Machte ich eine kleine änderung an der ursprünglichen Lösung. Anstelle der überprüfung den Typ der Eigenschaft zugeordnet werden soll, habe ich den filter in ForAllPropertyMaps, überprüfen Sie den Typ der Quell-Objekt, so dass der benutzerdefinierte Konfliktlöser gilt nur für Karten aus dieser Quelle-Objekt. Aber der filter können gesetzt werden, um etwas als notwendig.
InformationsquelleAutor Tim
Ich habe exakt das gleiche Problem mit der Zuordnung von bis die Bedingungen der nicht-generischen Typen. Hier ist, wie ich es gelöst.
Draht:
Den zweiten .FromMember ist erforderlich, damit der Wert für das Mitglied übergeben wird, der Wert resolver, eher als das vollständige Modell.
Den resolver, der wie folgt aussieht:
InformationsquelleAutor Chris Hynes