首页 > 解决方案 > Automapper 自定义地图使用“包含”来获取子项计数

问题描述

我有一个 asp net core 2.1 项目。db 上下文是用 EF 制作的。这是我的 SecGroups 和 SecGroupRights 数据库模型:

public partial class SecGroups
{
    public SecGroups()
    {
        SecGroupRights = new HashSet<SecGroupRights>();
    }

    public long Id { get; set; }
    public string Name { get; set; }
    public bool? IsReference { get; set; }
    public long? Provider { get; set; }
    public long? Class { get; set; }

    public SecGroups IdNavigation { get; set; }
    public SecGroups InverseIdNavigation { get; set; }
    public ICollection<SecGroupRights> SecGroupRights { get; set; }
}

public partial class SecGroupRights
{
    public long Id { get; set; }
    public long GroupId { get; set; }
    public long RightId { get; set; }

    public SecGroups Group { get; set; }
    public SecRights Right { get; set; }
}

这只是 SecGroups 和 SecGroupRights 之间简单的一对多关系。

如果我通过 SecGroups 获得_context,例如var grDB=_context.SecGroups.FirstOrDefault();我总是有grDB.SecGroupRightsnull (即使它有孩子)

我发现我必须使用“包含”来获取它才能让孩子们:

var grDB = await _context.SecGroups.Include(a => a.SecGroupRights)
.Where(a => a.Id == myID)
.FirstOrDefaultAsync();

这很好用,我可以访问 SecGroupRights 数据并最终获得他们的计数。

现在接下来要做的是从SecGroups这个自定义 AutoMapper 映射:

public class GroupsDto
{
    public long? Id { get; set; }
    public string Name { get; set; }
    public long? Provider { get; set; }
    public long? Rights { get; set; }
}

所以在“权利”字段中,我只想要孩子的数量。在我上面的场景中,这将是:

grDB.SecGroupRights.Count();

我尝试像这样进行映射:

        CreateMap<SecGroups, GroupsDto>(MemberList.Source)
            .ForMember(d => d.Rights, opt => opt.MapFrom(src => src.SecGroupRights.Count()));

不幸的是,问题是在映射 SecGroupRights 对象时为空,我总是得到 0 计数。

所以我尝试在我的 Mapping 助手中注入 _context 并最终得到这个:

        CreateMap<SecGroups, GroupsDto>(MemberList.Source)
        .ForMember(d => d.Rights, opt => opt.MapFrom(src => (
            _context.SecGroupRights.Where(a => a.GroupId==src.Id).Count()

        )));

但似乎我没有收到错误,也没有计数,所以我假设映射器无法访问_context.

有什么办法可以在我的映射器中得到这个计数?我错过了什么吗?提前致谢。

--------------------------------- 编辑:

映射不起作用,因为当我使用映射器时,源中没有 SecGroupRights。

因此,作为参考,好的映射是:

CreateMap<SecGroups, GroupsDto>(MemberList.Source)
.ForMember(d => d.Rights, opt => opt.MapFrom(src => src.SecGroupRights.Count()));

我这样称呼它:

var res= _context.SecGroups.Include(a => a.SecGroupRights).ToList();
var mapped = _mapper.Map<List<SecGroups>, List<GroupsDto>>(res);

标签: c#linqasp.net-coreautomapper

解决方案


映射不起作用,因为当我使用映射器时,源中没有 SecGroupRights。

因此,作为参考,好的映射是:

CreateMap<SecGroups, GroupsDto>(MemberList.Source)
.ForMember(d => d.Rights, opt => opt.MapFrom(src => src.SecGroupRights.Count()));

我这样称呼它:

var res= _context.SecGroups.Include(a => a.SecGroupRights).ToList();
var mapped = _mapper.Map<List<SecGroups>, List<GroupsDto>>(res);

推荐阅读