尝试从 QBO API 获取超过 1000 个客户和发票时出现异常

exception when trying to fetch more than 1 thousand customer(s) and invoice(s) from QBO API

我有 1000 多个客户和发票,我正在尝试将所有这些客户和发票提取到下拉列表中。

QBO 站点上的文档表明,如果我想将所有客户加载到一个网格中,我们应该需要使用分页,但我想要的是将所有客户和发票加载到一个网格中下拉列表。

当我尝试获取超过 1000 个客户和发票时出现以下异常:

Validation Exception was thrown.

Details: QueryValidationError: value 100000 is too large. Max allowed value is 1000.

我正在尝试使用以下代码获取所有客户

public static List<Customer> GetAllQBOCustomers(ServiceContext context)
{
   return Helper.FindAll<Customer>(context, new Customer(),1,100000);
}

您无法一次下载所有记录。这就是错误告诉你的 - 非常清楚。没有什么神奇的方法可以避免服务器的规则。

不过,我真的认为你不应该一次下载它们。下拉列表不是向用户显示大量数据的好方法。考虑用户体验——您是否想要滚动浏览包含数千名客户的列表以尝试找到您想要的客户?或者开始输入部分名称并弹出一个简短的可能匹配列表以供选择会更容易吗?

一种更加用户友好的实现方式是使用自动完成框而不是下拉列表,在用户输入几个字符后,它可以使用 AJAX 进行搜索API 用于名称或 ID 包含这些字符的客户。然后您每次只需要 return 少量记录,用户将不会因为在 10,000 条记录的列表底部找到客户而不得不滚动 10 分钟。

直接的答案是循环足够的次数以获得您需要的记录:

public static List<Customer> GetAllQBOCustomers(ServiceContext context)
{
    var list = new List<Customer>();
    for (int i=0; i<=10000; i+= 1000)
    {
        var results = Helper.FindAll<Customer>(context, new Customer(),i, 1000);
        list.AddRange(results);
    }
    return list;
}

或者如果您想尝试并行执行(并且 API 允许并发连接):

public static List<Customer> GetAllQBOCustomers(ServiceContext context)
{
    var bag = new ConcurrentBag<Customer>();
    Parallel.ForEach( Enumerable.Range(0, 10), i =>
    {
        var results = Helper.FindAll<Customer>(context, new Customer(),i * 1000, 1000);
        bag.AddRange(results);
    });
    return bag.ToList();
}

由于一系列调用可能会很昂贵,我建议您缓存结果。

我写了下面的代码并解决了我的问题。

1. First I get the count of all the customers 
2. Then I get all the customers in chunks and the chunk size is 1000 
3. Create a List for customers. 
4. Define 3 integer type variables for counting. 
5. After that use do-while loop  
6. Add all the customers are added to the main customer list


        string strQuery = "Select Count(*) From Customer";
        string custCount = qboAccess.GetCutomerCount(qboInz.QboServiceContext, strQuery);
        List<qboData.Customer> customers = new List<Customer>();
        int maxSize = 0;
        int position = 1;
        int count = Convert.ToInt32(custCount);
        do
        {
          var custList = qboAccess.GetAllQBOEntityRecords(qboInz.QboServiceContext, new Customer(), position, 1000);
          customers.AddRange(custList);
          maxSize += custList.Count();
          position += 1000;
        } while (count > maxSize);