我在 android room 中定义了多对多关系。连接表包含附加属性,但我认为这在这里并不重要。
当我执行数据库查询时,我得到了很多结果。对于许多人来说,我的意思是由于错误的关系而导致我不期望的结果。显然,我的数据库中有一堆
Event
和 TrackedArtist
行。另外我还有一些EventArtistCrossRef
行。可以说
现在当我拨打
getAllEventsWithEventsAndArtists()
时,我得到两个结果。一种根据 id 1 的事件,另一种根据 id 2 的事件。event
和 trackedArtists
是正确的。但是 artistsAtEvent
包含“错误”条目。在 id 为 2 的事件示例中,我想要获取行 3、4 和 5,但我还获取行 2。
我需要向 @Relation 或 @Query 添加一些内容吗?或者我是否必须编写一个自定义@Query,因为房间不适合这个用例?
这是我的代码:
@Entity(tableName = "event_table")
data class Event(
@PrimaryKey(autoGenerate = true)
@ColumnInfo("event_id")
var eventId: Long = 0L,
@ColumnInfo("name")
var name: String = "",
// Other attributes ...
)
@Entity(tableName = "tracked_artist_table")
data class TrackedArtist(
@PrimaryKey(autoGenerate = true)
@ColumnInfo("artist_id")
var artistId: Long = 0L,
@ColumnInfo(name = "name")
var name: String = "",
// other attributes ...
)
@Entity(
primaryKeys = ["event_id", "artist_id"],
foreignKeys = [
ForeignKey(
entity = Event::class,
parentColumns = ["event_id"],
childColumns = ["event_id"],
onDelete = ForeignKey.CASCADE
),
ForeignKey(
entity = TrackedArtist::class,
parentColumns = ["artist_id"],
childColumns = ["artist_id"],
onDelete = ForeignKey.CASCADE
)
]
)
data class EventArtistCrossRef(
@ColumnInfo("event_id", index = true)
var eventId: Long,
@ColumnInfo("artist_id", index = true)
var artistId: Long,
// the mentioned before other attributes on junction table
)
data class EventWithEventsAndArtists(
@Embedded
var event: Event,
@Relation(
parentColumn = "event_id",
entityColumn = "artist_id",
associateBy = Junction(EventArtistCrossRef::class)
)
val artists: List<TrackedArtist>,
@Relation(
parentColumn = "event_id",
entityColumn = "artist_id",
associateBy = Junction(
value = EventArtistCrossRef::class,
parentColumn = "event_id",
entityColumn = "artist_id"
)
)
var artistsAtEvent: List<EventArtistCrossRef>
)
@Dao
interface EventDao {
@Transaction
@Query("SELECT * from event_table ORDER BY lower(name) ASC")
fun getAllEventsWithEventsAndArtists(): LiveData<List<EventWithEventsAndArtists>>
// other queries ...
}
我认为您的问题是您告诉 Room 从 event_table 中选择事件,并将 eventartistcrossref 表与 event_table 作为连接点连接起来,然后再次连接 eventartistcrossref 表,因此排列大于预期。
使用您的代码和以下活动代码(注意
.allowMainThreadQueries
是为了简洁和方便而使用的)来模仿您正在做的事情,但始终使用唯一的 id(艺术家 id 为 10、20、30 和 40,而不是 1-4): -
lateinit var db: TheDatabase
lateinit var dao: EventDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getEventDao()
dao.insert(Event(1,"Event1"))
dao.insert(Event(2,"Event2"))
dao.insert(TrackedArtist(10,"TA10"))
dao.insert(TrackedArtist(20,"TA20"))
dao.insert(TrackedArtist(30,"TA30"))
dao.insert(TrackedArtist(40,"TA40"))
dao.insert(EventArtistCrossRef(1,10))
dao.insert(EventArtistCrossRef(1,20))
dao.insert(EventArtistCrossRef(2,10))
dao.insert(EventArtistCrossRef(2,30))
dao.insert(EventArtistCrossRef(2,40))
for(eweaa in dao.getAllEventsWithEventsAndArtists()) {
val taoutput = StringBuilder()
for (ta in eweaa.artists) {
taoutput.append("\n\tNames is ${ta.name} artistId is ${ta.artistId}")
}
val aaeoutput = StringBuilder()
for (aae in eweaa.artistsAtEvent) {
aaeoutput.append("\n\tEventID=${aae.eventId} ArtistId=${aae.artistId}")
}
Log.d("DBINFO","Event Name is ${eweaa.event.name} Event ID is ${eweaa.event.eventId}" +
".\nThere are ${eweaa.artists.size} tacked artists; they are ${taoutput}" +
".\nThere are ${eweaa.artistsAtEvent.size} artistsAtEvents; they are ${aaeoutput}")
}
}
结果是:-
D/DBINFO: Event Name is Event1 Event ID is 1.
There are 2 tacked artists; they are
Names is TA10 artistId is 10
Names is TA20 artistId is 20.
There are 3 artistsAtEvents; they are
EventID=1 ArtistId=10
EventID=2 ArtistId=10
EventID=1 ArtistId=20
D/DBINFO: Event Name is Event2 Event ID is 2.
There are 3 tacked artists; they are
Names is TA10 artistId is 10
Names is TA30 artistId is 30
Names is TA40 artistId is 40.
There are 4 artistsAtEvents; they are
EventID=1 ArtistId=10
EventID=2 ArtistId=10
EventID=2 ArtistId=30
EventID=2 ArtistId=40
即跟踪的艺术家符合预期,但由于使用交叉引用作为连接点的交叉引用的非常规(如果这是正确的词)连接产生了意想不到的结果(我相信,由于与交叉引用的艺术家两个事件).
很难准确理解你想要实现的目标。