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

Xamarin Forms CollectionView搜索展示Azure Cosmos DB数据时出现重复问题

解决Xamarin Forms中CollectionView展示Cosmos DB数据时的重复问题

可能的原因及对应解决方案

1. 搜索事件并发触发导致重复加载

TextChanged事件会在用户输入的每一个字符变化时触发,如果前一次异步搜索请求还未完成,后一次请求又启动,就会导致多次向集合中添加数据,最终出现重复项。

解决方案:添加并发控制标识,避免重复发起请求:

// 类级别变量,标记当前是否正在执行搜索
private bool _isSearching;

void OnSearchCommunity(System.Object sender, Xamarin.Forms.TextChangedEventArgs e)
{
    var searchTerm = e.NewTextValue?.Trim() ?? string.Empty;
    
    // 如果正在搜索,直接返回,避免并发请求
    if (_isSearching) return;

    Device.BeginInvokeOnMainThread(async () =>
    {
        _isSearching = true;
        try
        {
            MyCommunityCollectionList.ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem;
            MyCommunityCollectionList.ItemsSource = await OnPersonSearch(searchTerm);
        }
        finally
        {
            // 无论请求成功或失败,都标记搜索结束
            _isSearching = false;
        }
    });
}

2. 复用ObservableRangeCollection导致数据残留

当前使用类级别的datasource变量,虽然每次调用Clear()清空,但如果异步操作时序出现问题,或者集合引用未正确更新,可能导致旧数据残留。

解决方案:每次搜索都创建新的ObservableRangeCollection,避免复用旧集合:

// 移除类级别的datasource和CommunityUser变量,改为方法内局部声明
async Task<ObservableRangeCollection<MyCommunityModel>> OnPersonSearch(string MyFriendName)
{
    // 每次搜索创建全新的集合实例
    var datasource = new ObservableRangeCollection<MyCommunityModel>();
    
    var UsersList = await UserManager.GetUserList(MyFriendName);

    foreach (var u in UsersList)
    {
        var CommunityUser = new MyCommunityModel();
        CommunityUser.MyId = u.MyId;
        CommunityUser.Username = u.Username;

        // 修正:使用原用户对象的图片地址,而非未赋值的CommunityUser属性
        var imageData = await AzureDatalakeBlob.GetFileAsync(AzureDatalakeBlob.ContainerType.leafwordsapp, u.UserImageBlobAdress);

        if (imageData != null)
        {
            CommunityUser.UserImage = ImageSource.FromStream(() => new MemoryStream(imageData));
        }
        else
        {
            CommunityUser.UserImage = ImageSource.FromResource("LeafWords.MyImages.MySettings.person.png");
        }

        datasource.Add(CommunityUser);
    }

    return datasource;
}

3. Cosmos DB查询返回重复数据

如果Cosmos DB的查询本身返回了重复的用户数据,可以在获取结果后进行去重处理:

public async static Task<List<MyUser>> GetUserList(string MyFriendName)
{
    MyFriendName = MyFriendName.ToLower();
  
    List<MyUser> UsersList = new List<MyUser>();

    // 替换字符串拼接,使用参数化查询避免SQL注入风险
    string sql = $"SELECT TOP 25 * FROM {collectionId} u WHERE CONTAINS(LOWER(u.username), @friendName)";
    QueryDefinition query = new QueryDefinition(sql)
        .WithParameter("@friendName", MyFriendName);

    using (FeedIterator<MyUser> iterator = container.GetItemQueryIterator<MyUser>(
     queryDefinition: query,
     requestOptions: new QueryRequestOptions()
     {
         MaxItemCount = -1,
     }))
    {
        while (iterator.HasMoreResults)
        {
            FeedResponse<MyUser> result = await iterator.ReadNextAsync();
            UsersList.AddRange(result.Resource);
        }

        // 按用户唯一ID去重,确保结果集中无重复项
        UsersList = UsersList.DistinctBy(u => u.MyId).ToList();
        return UsersList;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:50:43