You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Google Places API时,foreach循环中从XElement向List添加数据仅覆盖[0]位置而非填充整个列表的问题排查

解决你的Google Places API数据覆盖问题

问题出在哪?

兄弟,你这个问题其实很典型——每次循环都把整个placeDetailsModel列表给替换掉了!看你代码里的这行:

placeDetailsModel = doc2.Descendants("result").Select(...).ToList();

每次foreach循环执行这句的时候,都会创建一个全新的List,把原来的列表完全覆盖。所以不管循环多少次,最后列表里只会剩下最后一次请求到的那一条数据(也就是索引[0]的位置)。

怎么改?

咱们只需要把「重新赋值列表」改成「往现有列表里添加元素」就行,给你两种靠谱的写法:

写法一:用AddRange批量添加

因为单个place_id的Place Details返回结果只有一条,所以可以把查询到的小列表直接合并到主列表里:

static void Main(string[] args)
{
    string City_Name = "Gdańsk";
    var doc = XElement.Load($"https://maps.googleapis.com/maps/api/place/textsearch/xml?key={key}&query=restaurants+in+{City_Name}&language=pl&fields=place_id");
    List<PlaceIdModel> IdList = doc.Descendants("result").Select(n => new PlaceIdModel { PlaceId = n.Element("place_id").Value }).ToList();
    List<PlaceDetailsModel> placeDetailsModel = new List<PlaceDetailsModel>();
    
    foreach (var item in IdList)
    {
        var doc2 = XElement.Load($"https://maps.googleapis.com/maps/api/place/details/xml?key={key}&place_id={item.PlaceId}&language=pl&fields=name,vicinity,geometry/location,rating,website,opening_hours/weekday_text");
        
        // 先把当前place_id的详情存到临时列表
        var currentDetails = doc2.Descendants("result").Select(x => new PlaceDetailsModel
        {
            Name = x.Element("name").Value,
            Vicinity = x.Element("vicinity").Value,
            Rating = x.Element("rating")?.Value ?? "无评分", // 加空值判断,防止没有rating的场所报错
            Website = x.Element("website")?.Value ?? "无官网",
            Lat = x.Element("geometry").Element("location").Element("lat").Value,
            Lng = x.Element("geometry").Element("location").Element("lng").Value,
            Opening_hours = x.Descendants("weekday_text").Select(y => y.Value).ToList()
        }).ToList();
        
        // 把临时列表里的元素添加到主列表,而不是替换主列表
        placeDetailsModel.AddRange(currentDetails);
    };
}

写法二:直接取单个元素添加

既然单个place_id只会返回一条结果,咱们可以直接取第一个元素,然后添加到主列表,这样更直观:

static void Main(string[] args)
{
    string City_Name = "Gdańsk";
    var doc = XElement.Load($"https://maps.googleapis.com/maps/api/place/textsearch/xml?key={key}&query=restaurants+in+{City_Name}&language=pl&fields=place_id");
    List<PlaceIdModel> IdList = doc.Descendants("result").Select(n => new PlaceIdModel { PlaceId = n.Element("place_id").Value }).ToList();
    List<PlaceDetailsModel> placeDetailsModel = new List<PlaceDetailsModel>();
    
    foreach (var item in IdList)
    {
        var doc2 = XElement.Load($"https://maps.googleapis.com/maps/api/place/details/xml?key={key}&place_id={item.PlaceId}&language=pl&fields=name,vicinity,geometry/location,rating,website,opening_hours/weekday_text");
        
        // 获取单个详情对象
        var detail = doc2.Descendants("result").Select(x => new PlaceDetailsModel
        {
            Name = x.Element("name").Value,
            Vicinity = x.Element("vicinity").Value,
            Rating = x.Element("rating")?.Value ?? "无评分",
            Website = x.Element("website")?.Value ?? "无官网",
            Lat = x.Element("geometry").Element("location").Element("lat").Value,
            Lng = x.Element("geometry").Element("location").Element("lng").Value,
            Opening_hours = x.Descendants("weekday_text").Select(y => y.Value).ToList()
        }).FirstOrDefault();
        
        // 确认获取到数据再添加,避免加null进去
        if (detail != null)
        {
            placeDetailsModel.Add(detail);
        }
    };
}

额外提醒

  1. 空值处理:我给你加了?.Value ?? "默认值"的判断,因为有些餐厅可能没有评分或者官网,直接访问Value会报空引用错误,这个一定要注意。
  2. API限流:Google Places API有请求次数限制,批量调用的时候最好加个小延迟(比如Thread.Sleep(100)),不然容易被限流,导致请求失败。

内容的提问来源于stack exchange,提问作者larsx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:42:38