Map linked members under condition with parameter

60 Views Asked by At

I have the following model and dtos:

//Model
    public class User
    {
        //Key
        public int UserId { get; set; }
        public string UserName { get; set; }

        public List<ElementMember> ElementMembers { get; set; }

    }
    public class ElementMember
    {
        //Foreign Key
        public int UserId { get; set; }
        //Foreign Key
        public int ElementId { get; set; }

        public bool IsActiveMember { get; set; }

        public virtual Element Element { get; set; }
        public virtual User User { get; set; }
    }
    public class Element
    {
        //Key
        public int ElementId { get; set; }
        public string ElementName { get; set; }

        public List<ElementMember> ElementMembers { get; set; }

    }

    //DTO
    public class ElementMemberDto
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        //Some properties
    }

    public class ElementDetailsDto
    {
        public int ElementId { get; set; }
        public string ElementName { get; set; }
        public ElementMemberDto ElementMember { get; set; }
    }

In my controller, with the help of Automapper, I would like to Project the User + ElementMember informations in the ElementDetailsDto object only if the ElementMember table has UserId equal to a controller supplied key + IsActiveMember == true. If not, this object in the DTO can remain null.

public bool GetElementDetailsController(int elementId)
    {
        ElementDetailsDto elementDetailsDto = _db.Elements.ProjectTo<ElementDetailsDto>().FirstOrDefault(e => e.ElementId == elementId);

        int userId = GetCurrentUserId();

        elementDetailsDto.ElementMember = _db.ElementMember.ProjectTo<ElementMemberDto>()
            .FirstOrDefault(e => e.UserId == userId && e.ElementId == elementId && e.IsActiveMember == true);
    }

Would be great if could avoid calling twice the database. I am just a bit lost with the advanced functionalities of Automapper.

Regards,

1

There are 1 best solutions below

0
mj1313 On

I am not sure if it can be done in just one query. But you can get it to work like below:

var mapElementDetails = new MapperConfiguration(cfg =>
    cfg.CreateMap<Element, ElementDetailsDto>());

var mapElementMember = new MapperConfiguration(cfg =>
    cfg.CreateMap<ElementMember, ElementMemberDto>()
    .ForMember(dto => dto.UserName, conf => conf.MapFrom(ol => ol.User.UserName)));

ElementDetailsDto elementDetailsDto = _db.Elements.ProjectTo<ElementDetailsDto>(mapElementDetails).FirstOrDefault(e => e.ElementId == elementId);


elementDetailsDto.ElementMember = _db.ElementMember
    .Where(e => e.UserId == userId && e.ElementId == elementId && e.IsActiveMember == true)
    .ProjectTo<ElementMemberDto>(mapElementMember).FirstOrDefault();