简体   繁体   English

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

[英]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.我在某个时候停下来,我不知道如何将项目的 map 列表转换为 ProjectResponse object 的列表。 ProjectResponse is a shorten version of Project model class, and its technically DTO object. ProjectResponse 是 Project model class 及其技术上的 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.所以我只设法到 map FirstOrDefault object,但基本上我需要遍历 CLient 拥有的每个项目,并将 map 添加到新的 ClientResponse 项目中。

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:它应该只有一个具有该 ID 的,因此应该使用 First、Single、FirstOrDefault 等方法,然后您可以转换项目:

//...
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:或者,如果您在ClientProject之间有一个导航属性,您可以像这样使用它:

//...
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.通过查看代码和阅读您的问题,我的印象是 client.Id 是独一无二的,并且可以有许多与之相关的项目。 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.具体来说, clientsDb.Where在实际情况下返回一个集合,您只希望一个客户端匹配该 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):在没有实际尝试您的代码的情况下,我认为如果您将其更改为这些方面的内容(正如我在对您的问题的评论中提到的, Single可能对您的业务逻辑更具表现力):

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.当然,假设 Projects 和 x.Projects 是同一类型。 You may still have to cast out the ProjectResponse, but now of course you won't be dealing with a collection within a collection:您可能仍然需要排除 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.Id,
            Code = x.Code,
            Name = x.Name,
        }).ToList()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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