3

我在我的 Android 应用程序中遇到了 ObjectBox 的问题。一切正常,除了这个问题,所以我知道我的实体类没问题。

这是一个库存,可以对多个商店(商店)进行库存。每个InventoryItem都是在进行盘点时扫描的产品。当清点结束时,从框中的数据生成一个或多个文本文件。

为每个商店生成一个文件,所以我有这个代码来查找哪些不同的商店被盘点:

Box<InventoryItem> box = app.getBoxStore().boxFor(InventoryItem.class);
long[] shopIds = box.query()
                    .build()
                    .property(InventoryItem_.shopId)
                    .distinct()
                    .findLongs();

当此代码运行时,我得到以下信息(仅堆栈跟踪的相关部分):

Caused by: java.lang.IllegalArgumentException: Property "shopId" is of type Relation, but we expected a property of type Long in this context
    at io.objectbox.query.PropertyQuery.nativeFindLongs(Native Method)
    at io.objectbox.query.PropertyQuery$2.call(PropertyQuery.java:213)
    at io.objectbox.query.PropertyQuery$2.call(PropertyQuery.java:210)
    at io.objectbox.BoxStore.callInReadTx(BoxStore.java:709)
    at io.objectbox.BoxStore.callInReadTxWithRetry(BoxStore.java:654)
    at io.objectbox.query.Query.callInReadTx(Query.java:273)
    at io.objectbox.query.PropertyQuery.findLongs(PropertyQuery.java:210)
    at br.com.donadio.inventario.view.ExportDialog$GenerateFilesAsync.doInBackground(ExportDialog.java:132)
    at br.com.donadio.inventario.view.ExportDialog$GenerateFilesAsync.doInBackground(ExportDialog.java:104)
    at android.os.AsyncTask$2.call(AsyncTask.java:305)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 

我也尝试.property(InventoryItem_.shop.targetIdProperty)在查询中使用,但它给出了完全相同的错误。我找不到另一种方法来做到这一点,也找不到修复我的代码的方法。

我正在使用 AndroidX(没关系),并且我的项目已正确设置。MinSdk 为 19,MaxSdk 为 28,targetSdk 为 28。ObjectBox 版本为 2.2.0。在运行 Android 7.1.1 的设备上进行调试。

这些是相关实体:

@Entity
public class InventoryItem
{
    @Id
    public long id;

    public String operator;

    public ToOne<Area> area;
    public long areaId; // expose relationship target ID

    public ToOne<Product> product;
    public long productId; // expose relationship target ID

    public ToOne<Shop> shop;
    public long shopId; // expose relationship target ID

    public Date timestamp;

    // ...
}

@Entity
public class Shop
{
    @Id(assignable=true)
    public long id;

    @Index @Unique
    public String name;

    @Backlink
    public ToMany<InventoryItem> inventoryItems;

    // ...
}
4

2 回答 2

1

在 ObjectBox 的 GitHub 和这里寻找了很多答案后,我想出了一个解决方案,基于项目 GitHub 上的这个答案

List<InventoryItem> items = box.getAll();
ArrayList<Shop> shops = new ArrayList<>();
for (InventoryItem item : items)
{
    Shop shop = item.shop.getTarget();
    if (!shops.contains(shop))
        shops.add(shop);
}

因此,我们只需找到所有内容,然后遍历列表,在 an 中获取不同的对象ArrayList(或者我可以将 Id 放入 a 中long[])。只需几行代码...

不过,我认为这是 ObjectBox 实现中的一个错误,因为它返回的是关系而不是长属性上的属性。我打开一个问题。

于 2018-12-21T14:37:39.570 回答
0

我发现的解决方法是使用您想要 ID 的对象作为起始类来编写查询。

在你的情况下,那将是:

QueryBuilder<Shop> qb = app.getBoxStore().boxFor(Shop.class).query(); // Start with Shop if what you need are Shop IDs
qb.link(Shop_.inventoryItems); // Filter on working inventoryItems links
long[] shopIds = qb.build()
                    .property(Shop_.id)
                    .distinct()
                    .findLongs(); // Get your IDs

代替

Box<InventoryItem> box = app.getBoxStore().boxFor(InventoryItem.class);
long[] shopIds = box.query()
                    .build()
                    .property(InventoryItem_.shopId)
                    .distinct()
                    .findLongs();
于 2021-11-23T20:50:20.637 回答