【问题标题】:Automapper Projection with Linq OrderBy child property error带有 Linq OrderBy 子属性错误的 Automapper 投影
【发布时间】:2017-02-18 09:27:41
【问题描述】:

我在使用 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();

作为一些附加信息,我可以使用 Projections 对父类的属性进行 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();

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

【问题讨论】:

    标签: linq-to-sql automapper entity-framework-core projection


    【解决方案1】:

    看起来问题是由OrganizationViewModel 类的OrganizationGroup 属性引起的 - 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));
    

    【讨论】:

    • 效果很好。非常感谢!
    • 如果这对其他人有帮助,我切换到 myget 上的当前开发版本,这似乎已得到解决。
    • 看起来该修复程序直到 2.0.0-preview1 才发布 - github.com/aspnet/EntityFramework/issues/6921
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多