Automapper Projection с ошибкой дочернего свойства Linq OrderBy

У меня возникла проблема с использованием проекции AutoMapper (версия 5.1.1) в сочетании с выражением свойства Linq OrderBy Child. Я использую Entity Framework Core (версия 1.0.0). Я получаю следующую ошибку:

"должен быть приводимым узлом"

Мои DTO-объекты следующие

public class OrganizationViewModel
    {
        public virtual int Id { get; set; }
        [Display(Name = "Organization Name")]
        public virtual string Name { get; set; }
        public virtual bool Active { get; set; }
        public virtual int OrganizationGroupId { get; set; }
        public virtual string OrganizationGroupName { get; set; }
        public virtual int StrategyId { get; set; }
        public virtual string StrategyName { get; set; }
        public virtual OrganizationGroupViewModel OrganizationGroup { get; set; }
    }

public class OrganizationGroupViewModel
    {
        public virtual int Id { get; set; }
        [Display(Name = "Organization Group Name")]
        public virtual string Name { get; set; }
        public virtual bool Active { get; set; }
    }

Мои соответствующие модели сущностей таковы:

public class Organization
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string TimeZone { get; set; }
        public bool Active { get; set; }
        //FKs
        public int OrganizationGroupId { get; set; }
        public int StrategyId { get; set; }
        //Navigation
        public virtual OrganizationGroup OrganizationGroup { get; set; }
        public virtual Strategy Strategy { get; set; }
        [JsonIgnore]
        public virtual List<AppointmentReminder> AppointmentReminders { get; set; }
    }

public class OrganizationGroup
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Active { get; set; }

        public virtual List<Organization> Organizations { get; set; }
    }

Мои профили AutoMapper следующие:

public class OrganizationMapperProfile : Profile
    {
        public OrganizationMapperProfile()
        {
            CreateMap<Task<Organization>, Task<OrganizationViewModel>>();
            CreateMap<Organization, OrganizationViewModel>()
                .ForMember(dest => dest.OrganizationGroupName, opt => opt.MapFrom(src => src.OrganizationGroup.Name));
            CreateMap<OrganizationInput, Organization>()
                .ForMember(x => x.Id, opt => opt.Ignore());
        }
    }

public class OrganizationGroupMapperProfile : Profile
    {
        public OrganizationGroupMapperProfile()
        {
            CreateMap<Task<OrganizationGroup>, Task<OrganizationGroupViewModel>>();
            CreateMap<OrganizationGroup, OrganizationGroupViewModel>();
            CreateMap<OrganizationGroupInput, OrganizationGroup>()
                .ForMember(x => x.Id, opt => opt.Ignore());
        }
    }

Когда я запускаю следующие операторы, я могу запустить и получить результаты из первых 2 операторов:

var tmp = await _context.Organizations.Include(x => x.OrganizationGroup).OrderBy(x => x.OrganizationGroup.Name).ToListAsync();
var tmp4 = await _context.Organizations.Include(x => x.OrganizationGroup).OrderBy("OrganizationGroup.Name").ToListAsync();

Но когда я добавляю ProjectTo, я получаю ошибку, указанную выше:

var tmp5 = await _context.Organizations.Include(x => x.OrganizationGroup).OrderBy(x => x.OrganizationGroup.Name).ProjectTo<OrganizationViewModel>().ToListAsync();
var tmp6 = await _context.Organizations.Include(x => x.OrganizationGroup).OrderBy("OrganizationGroup.Name").ProjectTo<OrganizationViewModel>().ToListAsync();

В качестве дополнительной информации я могу использовать OrderBy с проекциями, работающими со свойствами родительского класса, такими как:

var tmp7 = await _context.Organizations.Include(x => x.OrganizationGroup).OrderBy(x => x.Name).ProjectTo<OrganizationViewModel>().ToListAsync();
var tmp8 = await _context.Organizations.Include(x => x.OrganizationGroup).OrderBy("Name").ProjectTo<OrganizationViewModel>().ToListAsync();

Кто-нибудь сталкивался с этим вопросом раньше? Похоже, я пытаюсь сделать что-то, что в противном случае не поддерживается, это дизайн? Спасибо за любую помощь / понимание.

1 ответ

Решение

Похоже, проблема вызвана OrganizationGroup собственность OrganizationViewModel класс - AutoMapper генерирует нулевую проверку, которая не нравится EF Core в комбинации с вашим OrderBy (Я думаю, что только одна из многих ошибок в настоящее время в EF Core). Это может быть легко воспроизведено следующим простым ручным проекционным запросом:

var tmp5a = _context.Organizations
    .OrderBy(x => x.OrganizationGroup.Name)
    .Select(e => new OrganizationViewModel
    {
        Id = e.Id,
        OrganizationGroup = e.OrganizationGroup != null ? new OrganizationGroupViewModel
        {
             Id = e.OrganizationGroup.Id,
             Name = e.OrganizationGroup.Name,
             Active = e.OrganizationGroup.Active,
        } : null,
    })
    .ToList();

Чтобы решить эту проблему, настройте AutoMapper, чтобы он не генерировал null проверьте это свойство следующим образом:

CreateMap<Organization, OrganizationViewModel>()
    .ForMember(dest => dest.OrganizationGroup, opt => opt.AllowNull())
    .ForMember(dest => dest.OrganizationGroupName, opt => opt.MapFrom(src => src.OrganizationGroup.Name));
Другие вопросы по тегам