分层数据和用 LINQ 合并两个数据集

问题描述 投票:0回答:1

我有两个后端服务,其中一个返回嵌套对象,另一个返回基于另一个对象的 ID 的对象列表。像这样的东西:

Api 层中的 DTO:

public static class GetData
{
    public record Country
    {
        public Guid Id { get; set; }
        public List<State> States { get; set; }
    }

    public record State
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public List<City> Cities { get; set; }
    }

    public record City
    {
        // this Id is stored in Service B's DB as ItemId
        public Guid Id { get; set; }
        public string Name { get; set; }
        public Location Location { get; set; }
    }

    // From service B
    public record Location
    {
        public Guid Id { get; set; }
        public Guid ItemId { get; set; }
        public string Name { get; set; }
        public string Latitude { get; set; }
        public string Longitude { get; set; }
    }
}

在我的api层,我必须为上面的数据结构调用服务A不包括City.Location和Location。然后我需要用一个简单的城市 ID 列表调用服务 B。第二次调用返回一个位置列表,其中按某种顺序包含那些城市 ID(如 ItemId)。然后我需要合并这两个集合并一次返回上面的结构。例如

// this part works fine for getting the data:
var country = await _serviceRequestA.GetCountryData();
var ids = country.States.SelectMany(x => x.Cities).Select(x => x.Id).ToList();
var locations = await _serviceRequestB.GetLocations(ids); 

通过 city.Id 和 location.ItemId 将每个城市与每个位置匹配,找到后将 ID、名称、纬度、经度作为位置对象附加到正确的城市。 例如,在类似 javascript 的伪代码中(这不是实际代码,只是概念):

在我的处理程序中,它被调用并将数据返回给 API 控制器,这是概念:

...country,
...country.states,
...country.states.cities.forEach(c => {
      locations.forEach(l => {
        if (c.Id == l.ItemId) {
          c.Location = new Location { l.Id, l.Name, l.Longitude, l.Latitude } 
        }
      }
   }

上面的合并逻辑是为了说明我在概念上试图用这些数据做什么。除了简单的 wheres 和 selects 之外,我对 C# 或 LINQ 没有那么丰富的经验。

任何指导?

c# linq asp.net-core asp.net-web-api nested-lists
1个回答
0
投票

从你的问题和评论来看,我认为这就是你想要的。

cities.ForEach(c =>
            {
                c.Location = locations.Where(x => x.ItemId == c.Id).FirstOrDefault();
            });

或者如果你不想包含

Itemid
的值,你也可以使用这个代码:

cities.ForEach(c =>
            {
                c.Location = locations.Where(x => x.ItemId == c.Id).Select(x => new LocationA(){Id= x.Id,Name= x.Name,Latitude=x.Latitude,Longitude=x.Longitude}).FirstOrDefault();
            });
© www.soinside.com 2019 - 2024. All rights reserved.