c# - custom - automapper runtime mapping




AutoMapper.Map ignora tutte le proprietà del valore Null dall'oggetto di origine (4)

Sto provando a mappare 2 oggetti dello stesso tipo. Quello che voglio fare è AutoMapper per igonore a tutte le proprietà, che hanno valore Null nell'oggetto sorgente e mantengono il valore esistente nell'oggetto di destinazione.

Ho provato a utilizzare questo nel mio "repository", ma non sembra funzionare.

Mapper.CreateMap<TEntity, TEntity>().ForAllMembers(p => p.Condition(c => !c.IsSourceValueNull));

Quale potrebbe essere il problema?


Finora l'ho risolto in questo modo.

foreach (var propertyName in entity.GetType().GetProperties().Where(p=>!p.PropertyType.IsGenericType).Select(p=>p.Name))
   {
      var value = entity.GetType().GetProperty(propertyName).GetValue(entity, null);
      if (value != null)
      oldEntry.GetType().GetProperty(propertyName).SetValue(oldEntry, value, null);
    }

ma ancora sperando di trovare una soluzione usando AutoMapper


Interessante, ma il tuo tentativo originale dovrebbe essere la strada da percorrere. Sotto test è verde:

using AutoMapper;
using NUnit.Framework;

namespace Tests.UI
{
    [TestFixture]
    class AutomapperTests
    {

      public class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public int? Foo { get; set; }
        }

        [Test]
        public void TestNullIgnore()
        {
            Mapper.CreateMap<Person, Person>()
                    .ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));

            var sourcePerson = new Person
            {
                FirstName = "Bill",
                LastName = "Gates",
                Foo = null
            };
            var destinationPerson = new Person
            {
                FirstName = "",
                LastName = "",
                Foo = 1
            };
            Mapper.Map(sourcePerson, destinationPerson);

            Assert.That(destinationPerson,Is.Not.Null);
            Assert.That(destinationPerson.Foo,Is.EqualTo(1));
        }
    }
}

Sovraccarico di Condition con 3 parametri rendiamo l'espressione equivalente al tuo esempio p.Condition(c => !c.IsSourceValueNull) :

Firma del metodo:

void Condition(Func<TSource, TDestination, TMember, bool> condition

Espressione equivalente:

CreateMap<TSource, TDestination>.ForAllMembers(
    opt => opt.Condition((src, dest, sourceMember) => sourceMember != null));

Work Around - Aggiungi la proprietà DataMember nel tipo di destinazione [DataMember (EmitDefaultValue = false)] rimuoverà la proprietà se il valore di origine è null.

[DataContract]
class Person
{
    [DataMember]
    public string Name { get; set; } 

    [DataMember]
    public int? Age { get; set; } 

    [DataMember(EmitDefaultValue = false)]
    public string Role { get; set; } 
}

se il valore del ruolo è null, la proprietà del ruolo verrà rimossa.





automapper