带有 Linq OrderBy 子属性错误的 Automapper 投影 [英] Automapper Projection with Linq OrderBy child property error

查看:29
本文介绍了带有 Linq OrderBy 子属性错误的 Automapper 投影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 AutoMapper(5.1.1 版)投影结合 Linq OrderBy Child 属性表达式时遇到问题.我正在使用 Entity Framework Core(版本 1.0.0).我收到以下错误:

I am having an issue using an AutoMapper (version 5.1.1) projection combined with a Linq OrderBy Child property expression. I am using Entity Framework Core (version 1.0.0). I am getting the following error:

必须是可约节点"

我的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; }
    }

我对应的实体模型如下:

My corresponding entity models are as follows:

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 配置文件如下:

My AutoMapper profiles are as follows:

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 个语句中获得结果:

When I run the following statements I am able to run and get results from the first 2 statements:

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 时,出现上面列出的错误:

But when I add the ProjectTo I get the error listed above:

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,例如:

As some additional information, I am able to OrderBy with Projections working on properties of the parent class, such as:

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();

有人遇到过这个问题吗?看起来我正在尝试做一些不支持的事情,这是设计使然吗?感谢您提供任何帮助/见解.

Anyone run into this issue before? Looks like I'm trying to do something that is otherwise not supported, is that by design? Thanks for any help/insight.

推荐答案

看起来问题是由 OrganizationViewModel 类的 OrganizationGroup 属性引起的 - AutoMapper 生成空值检查哪个 EF Core 不喜欢与您的 OrderBy 组合(我猜这只是 EF Core 中当前的众多错误之一).它可以通过以下简单的手动投影查询轻松重现:

Looks like the problem is caused by the OrganizationGroup property of the OrganizationViewModel class - AutoMapper generates a null check which EF Core doesn't like in the combination with your OrderBy (I guess just one of the many bugs currently in EF Core). It can easily be reproduced by the following simple manual projection query:

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 检查,如下所示:

To fix the issue, configure AutoMapper to not generate null check for that property as follows:

CreateMap<Organization, OrganizationViewModel>()
    .ForMember(dest => dest.OrganizationGroup, opt => opt.AllowNull())
    .ForMember(dest => dest.OrganizationGroupName, opt => opt.MapFrom(src => src.OrganizationGroup.Name));

这篇关于带有 Linq OrderBy 子属性错误的 Automapper 投影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆