简体   繁体   中英

How to map to another object list with help of linq lambda select

I have stopped at some point, where I dont know how to map list of Project to list of ProjectResponse object. ProjectResponse is a shorten version of Project model class, and its technically DTO object.

Here is the thing

public async Task<IEnumerable<ClientResponse>> Handle(GetClientsQuery query, CancellationToken cancellationToken)
{
    List<Client> clientsDb = await _context.Clients.Include(x => x.Projects).Where(client => !client.IsDeleted).ToListAsync();
    Result<List<UserData>> clientsIdentity = await _identityService.GetClients(clientsDb.Select(x => x.IdentityId).ToList());

    List<ClientResponse> clients = new List<ClientResponse>();


    foreach (var client in clientsIdentity.Data)
    {
        clients.Add(new ClientResponse
        {
            //two properties are filling up from clientsIdentity.Data 
            Email = client.Email,
            Name = client.Name,

            //second two from clientsDb
            Id = clientsDb.FirstOrDefault(x => x.IdentityId.Equals(client.Id)).Id,

            //One client has multiple projects (List<Project>)
            //List<Project> need to be transformed and packed to List<ProjectResponse> (it's a dto object for Project model)
            Projects = clientsDb.Where(x => x.IdentityId.Equals(client.Id)).Select(x => new ProjectResponse
            {
                //it shouldnt be FirstOrdefault - it now picksup always just from the first one, it should be some kind of foreach of projects..
                Id = x.Projects.FirstOrDefault().Id,
                Code = x.Projects.FirstOrDefault().Code,
                Name = x.Projects.FirstOrDefault().Name,
            }).ToList()
        });
    }

    return clients;
}

So I managed to map only FirstOrDefault object, but essentially I need to walk through each project that CLient has, and to map to a new ClientResponse projects, actually to add them.

I think your problem is that for each client that is in iteration you retrieve many clients. It should be only one with that id, so methods like First, Single, FirstOrDefault, ... should be used and then you can transform Projects:

//...
Projects = clientsDb.Single(x => x.IdentityId.Equals(client.Id)).Projects.Select(x => new ProjectResponse...

Or, if you have a navigation property between Client and Project you can use it like this:

//...
Projects = client.Projects.Select(x => new ProjectResponse...

It appears as though you have a misplaced where.

From looking at the code and reading your issue, I'm under the impression that client.Id is unique, and can have many projects associated with it. So this block:

        Projects = clientsDb.Where(x => x.IdentityId.Equals(client.Id)).Select(x => new ProjectResponse
        {
            //it shouldnt be FirstOrdefault - it now picksup always just from the first one, it should be some kind of foreach of projects..
            Id = x.Projects.FirstOrDefault().Id,
            Code = x.Projects.FirstOrDefault().Code,
            Name = x.Projects.FirstOrDefault().Name,
        }).ToList()

Specifically the clientsDb.Where is returning a collection when the reality is, you only expect ONE client to match that Id.

Without actually trying your code, I think if you change it to something along these lines (as I mentioned in the comment to your question, Single may be more expressive to your business logic):

Projects = clientsDb.FirstOrDefault(x => x.IdentityId.Equals(client.Id)).Select(x => x.Projects).ToList()

That of course, assumes Projects and x.Projects are the same type. You may still have to cast out the ProjectResponse, but now of course you won't be dealing with a collection within a collection:

           {
            //it shouldnt be FirstOrdefault - it now picksup always just from the first one, it should be some kind of foreach of projects..
            Id = x.Id,
            Code = x.Code,
            Name = x.Name,
        }).ToList()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM