我具有以下数据结构,该数据结构由提供者列表组成,具有产品,每种产品具有不同的类型
提供商类
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
}
}
]
}]
}
]
}
所以,当我尝试使用以下查询来获取香蕉类型时,就会出现我遇到的问题
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的提供者ID 1,我仍会得到“厄瓜多尔Prem”,并且该提供者必须以“哥斯达黎加”和“巴西”类型返回。
答案 0 :(得分:1)
您遇到两个或三个问题之一:
1。)您的API返回BEGIN ... END
的{{1}}是product type
,但是Provider1和Provider2都得到id
,因此{{1 }保存具有Banana
的}},此后保存具有相同ID的id=10;Banana
的{{1}}(因此用Banana
覆盖原始的Provider1
例如“合并”。
因此,您应该引入一个手动计算的组合键,而不是直接将API响应映射到RealmObjects,该键很可能是一个String字段,其中包含与ProductTypeID串联的ProviderID。
Banana
我希望这不是同步领域!
2。)您可能出于“方便”的考虑将JSON对象直接映射到Realm,但这使您无法为查询设置最佳模式。
实际上,“提供者”似乎并不特别重要,除了特定的香蕉属于某个提供者之外。可以将其建模为字段,而不是对象链接。
Provider2
最重要的是,Banana
只是两个可以轻松合并到Provider1
中的字段。而且,如果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;
}
类型可以属于多个产品和多个提供商,那么它还应该具有一个由这三个ID构成的复合密钥!
// 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;
}
3。)一旦拥有 ,就可以轻松地依靠直接检查是否也保存到packaging
中的ProductType
,或者依靠Ecuador Prem
来反转查询的方向。
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;
}
之后您可以执行以下任一操作
providerId
因此,如果此应用尚未投入生产,则完全重新考虑您的Realm模式。