我有以下数据结构,其中包含提供商列表,包含产品,每个产品都有不同的类型
提供者类
public class Provider extends RealmObject {
@SerializedName("id")
@PrimaryKey
public int providerId;
public String name;
public RealmList<Product> products;
}
产品类别
public class Product extends RealmObject {
@SerializedName("id")
@PrimaryKey
public int productId;
public String name;
public RealmList<ProductType> types;
}
产品类型类
public class ProductType extends RealmObject {
@SerializedName("id")
@PrimaryKey
public int productTypeId;
public String name;
public Packaging packaging; }
这是加载到域中的JSON示例:
{
"providers": [{
"id": 1,
"name": "PROVIDER_1",
"products": [{
"id": 10,
"name": "Banana",
"types": [{
"id": 101,
"name": "Costa rica",
"packaging": {
"isFree": true,
"value": 0
}
},
{
"id": 102,
"name": "Brasil",
"packaging": {
"isFree": true,
"value": 0
}
}
]
}]
},{
"id": 4,
"name": "PROVIDER_2",
"products": [{
"id": 10,
"name": "Banana",
"types": [{
"id": 103,
"name": "Ecuador Prem",
"packaging": {
"isFree": true,
"value": 0
}
}
]
},
{
"id": 21,
"name": "Apple",
"types": [{
"id": 212,
"name": "Red del",
"packaging": {
"isFree": true,
"value": 0
}
}
]
}]
}
]
}
因此,当我尝试使用以下查询获取Bananas类型时,会出现我遇到的问题
RealmResults<Provider> results = mRealm.where(Provider.class).equalTo("providerId", providerId).findAll();
Product product = results.where().equalTo("providerId", providerId).findFirst().products.where().equalTo("productId", productId).findFirst();
RealmList<ProductType> types = product.types;
返回的类型列表总是给我第二个提供者的类型。在当前示例中,即使我请求提供者ID为PROVIDER_1,我也会收到“Ecuador Prem”,并且该提供者必须返回“Costa rica”和“Brasil”类型。
你有两个或三个问题之一:
1.)你的API返回product type
为id
为Banana
,但是你得到了Provider1和Provider2的id=10;Banana
,因此保存了Banana
的Provider1
,之后保存了具有相同ID的Banana
的Provider2
(因此用Banana
覆盖原始的Provider1
而不是“合并它们”(例如)。
因此,不应直接将API响应映射到RealmObjects,而是应该引入一个手动计算的复合键,它很可能是一个String字段,其中包含与ProductTypeID连接的ProviderID。
public class Product extends RealmObject {
@PrimaryKey
public String providerWithProductId; // must be set, like "$PROVIDERID_$PRODUCTID"
@Index
public int productId;
public String name;
public RealmList<ProductType> types;
}
我希望这不是同步领域!
2.)您正在将JSON对象直接映射到Realm,可能是出于“方便”,但这使您无法为查询设置最佳模式。
实际上,除了特定香蕉属于某个提供者之外,“提供者”似乎并不特别重要;这可以建模为字段,而不是对象链接。
// public class Provider extends RealmObject {
//
// @SerializedName("id")
// @PrimaryKey
// public int providerId;
// public String name;
// public RealmList<Product> products;
//
// }
public class Product extends RealmObject {
@PrimaryKey
public String providerWithProductId; // must be set
@Index
public int productId;
public String productName;
@Index
public int providerId;
public String providerName;
public RealmList<ProductType> productTypes;
}
最重要的是,packaging
只是两个可以很容易合并到ProductType
的领域。而且,如果Ecuador Prem
类型可以属于多个产品和多个提供者,那么它还应该具有由所有这三个ID构建的复合键!
public class ProductType extends RealmObject {
@PrimaryKey
public String providerWithProductWithProductTypeId; // you must fill this yourself
@Index
public int providerId;
@Index
public int productTypeId;
@Index
public int productId;
public String productTypeName;
//public Packaging packaging;
public boolean packagingIsFree;
public long packagingValue;
}
3.)一旦你有了这个,你可以轻松地直接检查providerId
也保存到ProductType
,或者依靠@LinkingObjects
来反转查询的方向。
public class ProductType extends RealmObject {
@PrimaryKey
public String providerWithProductWithProductTypeId; // you must fill this yourself
@Index
public int providerId;
@Index
public int productTypeId;
@Index
public int productId;
public String productTypeName;
//public Packaging packaging;
public boolean packagingIsFree;
public long packagingValue;
@LinkingObjects("productTypes")
public final RealmResults<Product> isTypeOfProducts = null;
}
之后你可以做任何一个
// RealmResults<Provider> resultsmRealm.where(Provider.class).equalTo("providerId", providerId).findAll();
// Product product = results.where().equalTo("providerId", providerId).findFirst().products.where().equalTo("productId", productId).findFirst();
// RealmList<ProductType> types = product.types;
RealmResults<ProductType> types = mRealm.where(ProductType.class).equalTo("providerId", providerId).findAll();
// or
RealmResults<ProductType> types = mRealm.where(ProductType.class).equalTo("isTypeOfProducts.providerId", providerId).findAll();
因此,如果此应用尚未投入生产,那么请完全重新考虑您的Realm架构。