我已按照Google的GithubBrowserSample开始使用Android架构组件和Retrofit。一切正常,但由于外键,我在自己的数据模型中遇到麻烦。
假设我有一个地方:
@Entity(tableName = "place",
foreignKeys = [
ForeignKey(entity = User::class, parentColumns = ["user_id"], childColumns = ["place_created_by_user_id"])
],
indices = [
Index(value = ["place_created_by_user_id"], name = "place_created_by_user_index")
])
data class Place(
@SerializedName("id")
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "place_id")
var id: Long,
@SerializedName("name")
@ColumnInfo(name = "place_name")
var name: String?,
@SerializedName("created_by_user_id")
@ColumnInfo(name = "place_created_by_user_id")
var createdByUserId: Long?,
)
一位用户:
@Entity(tableName = "user")
data class User(
@SerializedName("id")
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "user_id")
var id: Long,
@SerializedName("first_name")
@ColumnInfo(name = "user_first_name")
var firstName: String,
@SerializedName("last_name")
@ColumnInfo(name = "user_last_name")
var lastName: String,
)
根据Google的示例,获取存储库中的地点的方法是:
fun loadPlaces(): LiveData<Resource<List<Place>>> {
return object : NetworkBoundResource<List<Place>, List<Place>>(appExecutors) {
override fun saveCallResult(item: List<Place>) {
placeDao.insert(item)
}
override fun shouldFetch(data: List<Place>?): Boolean = true
override fun loadFromDb() = placeDao.getAll()
override fun createCall() = service.getPlaces()
override fun onFetchFailed() {
//repoListRateLimit.reset(owner)
}
}.asLiveData()
}
通常情况下,它只会工作(我尝试使用没有外键的实体)但由于外部约束而失败了:
android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
实际上,用户尚未加载。
所以在placeDao.insert(item)
之前,我必须加载每个用户以确保该地点能够找到他的用户。每个实体和每个外键都是一样的。
关于如何在这种架构下实现这一目标的任何想法?
关键是我在我的ViewModel中调用loadPlaces()
,如下所示:
class PlacesViewModel(application: Application) : BaseViewModel(application) {
val places: LiveData<Resource<List<Place>>> = repository.loadPlaces()
}
存储库本质上会加载附加到这些地方的用户......
感谢您的帮助。