1

I need to get invoices for a contact by contact Id, therefore I wrote Query 1 similar to Qusery 3 (which is working for payments). My objective is to query invoices from a field belongs to it's associated object Contact. But Query 1 returns 0 results.

Then I tried the way I querying for invoices, to query by a field belongs to Invoices. I was referring to the Xero C# code samples in GitHub. It's working and returns 10 results as expected.

Why can't I query from a ContactId field belongs to contact in an invoice?

Code

QUERY 1 (NOT WORKING - Return 0 results, expecting 10 results)

 var contact = _api.Contacts.Find().FirstOrDefault(c => c.AccountNumber == accountNumber);
            returnInvoiceList =
                _api.Invoices.Find()
                    .Where(c => c.Contact.Id == contact.Id)
                    .OrderBy(item => typeof(Invoice).GetProperty(
                        orderby, BindingFlags.Public | BindingFlags.Instance).GetValue(item))
                    .Skip(i * x)
                    .Take(x)
                    .ToList();

QUERY 2 (WORKING)

returnInvoiceList =
                    _api.Invoices.Where(string.Format("Reference == \"{0}\"", accountNumber)).Find()
                        .OrderBy(item => typeof(Invoice).GetProperty(
                            orderby, BindingFlags.Public | BindingFlags.Instance).GetValue(item))
                        .Skip(i * x)
                        .Take(x)
                        .ToList();

QUERY 3 (Similar pattern query to Query 1, working for payments)

 returnPaymentList =
                   _api.Payments.Find()
                       .Where(c => c.Invoice.Contact.Id == contact.Id)
                       .OrderBy(item => typeof(Payment).GetProperty(
                           orderby, BindingFlags.Public | BindingFlags.Instance).GetValue(item))
                       .Skip(i * x)
                       .Take(x)
                       .ToList();
4

1 回答 1

5

在您的 Query1 中,您似乎使用的是 Linq .Where 而不是包装器的开放式 .Where 子句。使用 Linq .Where 将在客户端执行过滤。使用包装器开放式 .Where 子句将允许在服务器端进行过滤,这意味着您只会收到与您的查询匹配的发票。

我建议您尝试替换查询的这一部分

_api.Invoices
    .Find()
    .Where(c => c.Contact.Id == contact.Id)

_api.Invoices
    .Where("Contact.ContactID == Guid(\"" + contact.Id +"\")")
    .Find()  

利用服务器端过滤来确保您只会收到具有正确联系 ID 的发票。

对于如何在 Query1 中找到您的联系人以及如何在 Query3 中找到您的付款,也可能值得您做一些类似的事情。

还值得注意的是,您最多只能返回 100 条记录,因为默认情况下包装器会分页发票。如果您希望返回超过 100 条记录,您将需要循环浏览页面,直到您不再收到更多记录,方法是在 .Find() 之前提供方法 .Page(x) ,其中 x 是您想要的页码。

这就是为什么您的 Query3 有效但您的 Query1 无效的原因。Payments 端点在 Xero 的 API 中尚不支持分页,因此您在连接的组织中接收所有付款,因此在客户端进行过滤就可以了,但对于 Query1,您只会收到 100 张发票(因为分页) 并且它们都不会与您的客户端 Linq .Where 匹配。

干杯,

马特

于 2015-12-17T22:42:14.533 回答