Autmapper ProjectTo因firstordefault而失败

时间:2018-01-16 20:01:25

标签: linq automapper projection

我使用AutoMapper ProjectTo将Person实体映射到EmployeeDto。在我的EmployeeDto中,我有一个我要捕获的AddressDto属性。因为Person有一个Address的集合我定义了我的映射来捕获第一个:

.ForMember(d => d.Address, s => s.MapFrom(m => m.Addresses.FirstOrDefault())

问题是当我在我的映射中包含它时,我收到一个错误,“不支持”指定类型成员“IsDeleted”...“IsDeleted是具有属性[NotMapped]的Person上的基本属性。我的EmployeeDto不包含IsDeleted属性。

当我查看IQueryable表达式属性时,我得到了这个:

System.Data.Entity.Core.Objects.ObjectQuery`1[MyProject.Data.Core.Entities.Person]
.MergeAs(MergeOption.AppendOnly)
.Where(
    // Quoted to induce a closure:
    a => a.FirstName.Contains(param.Value))
.Select(
    // Quoted to induce a closure:
    dto => new 0_Culture=neutral_PublicKeyToken=null>
    {
        IsDeleted = dto.IsDeleted,
        UpdateDate = dto.UpdateDate,
        CreateDate = dto.CreateDate,
        Id = dto.Id,
        …remaining Person entity properties removed for brevity,
        Addresses = dto.Addresses,
        Address = dto.Addresses.FirstOrDefault()
    })
.Select(

    // Quoted to induce a closure:
    dto => new EmployeeDto
    {
        …all employeedto property removed for brevity,
        Address = (dto.Address != null) ? new AddressDto { Id = dto.Address.Id } : null
    })

这是我的映射(ForSourceMember()部分是我尝试过的,但无法解决问题 - 无论是否有相同的结果):

configuration.CreateMap<Person, EmployeeDto>()
            .ForSourceMember(s => s.IsDeleted, x => x.Ignore())
            .ForSourceMember(s => s.CommonProperties, x => x.Ignore())
            .ForSourceMember(s => s.Events, x => x.Ignore())
            .ForMember(d => d.PersonId, s => s.MapFrom(m => m.Id))
            .ForMember(d => d.PersonType, s => s.UseValue(PersonTypes.Employee))                
            .ForMember(d => d.StatusType, s => s.MapFrom(m => m.PersonStatusType.Type))
            .ForMember(d => d.Status, s => s.MapFrom(m => m.PersonStatusType.Code))
            .ForMember(d => d.Address, s => s.MapFrom(m => m.Addresses.FirstOrDefault()))
            ;

My AddressDto对Address to AddressDto有类似的CreateMap定义。

此外,当这些相同的对象是另一个dto对象的子对象时,映射有效。希望这足以让某人认出我的问题。

编辑解决方法 - 添加条件会起作用。由于某种原因,它会阻止IQueryable表达式创建.Select(dto =&gt; new 0_Culture = neutral_publickkeytoken = null&gt; block:

.ForMember(d => d.Address, s => s.MapFrom(m => m.Addresses.Count > 0 ? m.Addresses.FirstOrDefault() : null)

1 个答案:

答案 0 :(得分:1)

这是EF Core问题,已在EF Core 3.0中修复。有关此问题的更多详细信息,请访问:https://github.com/dotnet/efcore/issues/15399

作为一种解决方法,您可以使用.Take(1)并将其投影到ICollection中。