Ошибки AutoMapper при отображении коллекций EF? - PullRequest
0 голосов
/ 09 января 2020

Я пытаюсь использовать Automapper Version 7 (из-за. Net 4.5 Framework Constraints) с EF 6 впервые для сопоставления DTO *

. Насколько я понимаю, это должно быть очень просто ... ... но не для меня.

Мне нужно указать это, поскольку я не могу понять, что я делаю неправильно.

Примеры классов

[Table("Vehicle")]
public partial class Vehicle
{
    public Vehicle()
    {
        TestDrive = new HashSet<TestDrive>();
    }

    public int Id { get; set; }

    [Required]
    public string Registration { get; set; }

    ... other props ...

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<TestDrive> TestDrives { get; set; }
}

public class VehicleDTO : BaseDTO
{
    public VehicleDTO()
    {

    }

    public int Id { get; set; }

    [Required]
    public string Registration { get; set; }

    ... other props ...

    I will add public List<TestDrive> TestDrives { get;set;} but for now i want this to be null on the entity.
}

public class BaseDTO
{
    //Attempting Generic Mapper Here but same issue when defined individually...
    public T1 Map<T1, T2>(T2 entity, MapperConfiguration mapperConfig = null)
    {
        IMapper mapper = (mapperConfig == null ? new MapperConfiguration(cfg=>cfg.CreateMap<T1,T2>()) : mapperConfig).CreateMapper();

        return mapper.Map<T1>(record);
    }
 }

 public class VehicleBL
 {
    public bool UpdateEntity (VehicleDTO record)
    {
       Vehicle entity = Map<Vehicle,VehicleDTO>(record);
       return _dal.Update(entity)
     }
  }

Это приводит к ошибкам в отображении для виртуальной коллекции TestDrive.

    Unmapped members were found. Review the types and members below.
    Add a custom mapping expression, ignore, add a custom resolver, or modify 
    the source/destination type
    For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
=============================================================================
AutoMapper created this type map for you, but your types cannot be mapped using the current configuration.
VehicleDTO -> Vehicle (Destination member list)
DTOs.VehicleDTO -> Database.Entities.Vehicle(Destination member list)

Unmapped properties:
TestDrives

Я перепробовал множество конфигураций сопоставления, кроме стандартных, но всегда появляется одна и та же ошибка .....

Vehicle entity = Map<Vehicle,VehicleDTO>(record, new MapperConfiguration(cfg => cfg.CreateMap<Vehicle, VehicleDTO>(MemberList.None));
Vehicle entity = Map<Vehicle,VehicleDTO>(record, new MapperConfiguration(cfg => cfg.CreateMap<Vehicle, VehicleDTO>(MemberList.Destination));
Vehicle entity = Map<Vehicle,VehicleDTO>(record, new MapperConfiguration(cfg => cfg.CreateMap<Vehicle, VehicleDTO>(MemberList.Source));

Also Tried 
.ForMember(x=>x.TestDrive,opt => opt.Ignore());
.ForSourceMember(x=>x.TestDrive,opt => opt.Ignore());

Found some extensions (which seemed like hacks tbh but figured dont have much to lose)
        public static IMappingExpression<TSource, TDestination> IgnoreAllDestinationVirtual<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        var desType = typeof(TDestination);
        foreach (var property in desType.GetProperties().Where(p => p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal))
        {
            expression.ForMember(property.Name, opt => opt.Ignore());
        }

        return expression;
    }

    public static IMappingExpression<TSource, TDestination> IgnoreAllSourceVirtual<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        var srcType = typeof(TSource);
        foreach (var property in srcType.GetProperties().Where(p => p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal))
        {
            expression.ForSourceMember(property.Name, opt => opt.Ignore());
        }

        return expression;
    }

  Which resulted in....

  Vehicle entity = Map<Vehicle,VehicleDTO>(record, new MapperConfiguration(cfg => cfg.CreateMap<Vehicle, VehicleDTO>().IgnoreAllSourceVirtual());
  Vehicle entity = Map<Vehicle,VehicleDTO>(record, new MapperConfiguration(cfg => cfg.CreateMap<Vehicle, VehicleDTO>().IgnoreAllDestinationVirtual());

Я знаю некоторые из этих попытки не должны работать, но после попытки того, что должно сработать, я прибег к попыткам всех опций, по крайней мере, получить другую ошибку или что-то, но нет ...

В конечном счете, я не могу прочитать проблему от сущности к DTO, но когда я попытаться преобразовать обратно, чтобы добавить или обновить .... не работает из-за несопоставленных "TestDrives"

Есть ли у вас какие-либо предложения?

...