Как создать запрос на соединение, который возвращает значение из самого соединения? - PullRequest
0 голосов
/ 03 ноября 2019

Я пытаюсь запросить персонажа с его статистикой, проблема в том, что таблица соединений содержит значение статистики. Например, символом является Фред, статистика - ловкость, а значение - 10. Значение, которое имеет Фред, - статистика ловкости, и его значение равно 10. Можно ли написать класс данных с @Relation и Junction для запросадля этого?

Я не вижу способа сделать это.

data class CharacterWithStatsEntity(
    @Embedded val character: CharacterEntity,
    @Relation(
        parentColumn = "id",
        entityColumn = "id",
        entity = StatsEntity::class,
        associateBy = Junction(
            value = CharactersStatsEntity::class,
            parentColumn = "characterId",
            entityColumn = "statsId"
        )
    ) val stats: List<StatsEntity>
)

Код, который я предоставляю, не возвращает значение из соединения. StatsEntity содержит только имя статистики, мне понадобится новый объект StatWithValue, который будет сочетать StatEntity и CharactersStatsEntity, и он будет содержать имя и значение статистики для конкретного символа.

1 Ответ

0 голосов
/ 04 ноября 2019

Это не совсем понятно без включения @Dao, @Entities и вызывающего кода.

Тем не менее, следующие примеры, основанные на доступной информации, являются примером получения значений.

  • Обратите внимание, что столбцы в правах были использованы однозначно / более легко различимы уникальные имена.

Сначала 3 основных объекта, которые определяют 3 таблицы, а именно: -

  • таблица CharacterEntity ,
  • таблица StatsEntity и таблица
  • CharactersStats (таблица соединений).

: -

@Entity
class CharacterEntity (

    @PrimaryKey
    var characterId: Long?,
    var name: String
)

@Entity
data class StatsEntity (

    @PrimaryKey
    var statsId: Long?,
    var statsName: String
)

@Entity(primaryKeys = ["characterIdReference","statsIdReference"])
data class CharacterStatsEntity (
    val characterIdReference: Long,
    val statsIdReference: Long
    )

Класс CharacterWithStatsEntity

data class CharacterWithStatsEntity(
    @Embedded val character: CharacterEntity,
    @Relation(
        parentColumn = "characterId",
        entityColumn = "statsId",
        entity = StatsEntity::class,
        associateBy = Junction(
            value = CharacterStatsEntity::class,
            parentColumn = "characterIdReference", 
            entityColumn = "statsIdReference"
        )
    ) val stats: List<StatsEntity>
)

Дао, позволяющий добавлять символы, статистику и соединения ичтобы разрешить извлечение через соединение: -

@Dao
interface CharacterStatsDao {
    @Insert
    fun insertCharacter(characterEntity: CharacterEntity) :Long

    @Insert
    fun insertStats(statsEntity: StatsEntity) :Long

    @Insert
    fun insertCharacterStatsJunction(characterStatsEntity: CharacterStatsEntity) :Long

    @Query("SELECT * FROM characterentity")
    fun getAllCharactersWithStats() : List<CharacterWithStatsEntity>
}

И, наконец, вызывающий код, который добавляет 2 символа и 4 статистики и соединения с символом Fred, имеющим Stat1 и Stat4, и символом Mary, имеющим Stat2 и Stat4, а затем, наконец,отчет о символах и их статистике с помощью класса CharactersWithStatsEntity : -

    val characterStatsDao = db.characterStatsDao()
    var char1 = characterStatsDao.insertCharacter(CharacterEntity(null,"Fred"))
    var char2 = characterStatsDao.insertCharacter(CharacterEntity(null,"Mary"))
    var stat1 = characterStatsDao.insertStats(StatsEntity(null,"STAT1"))
    var stat2 = characterStatsDao.insertStats(StatsEntity(null,"STAT2"))
    var stat3 = characterStatsDao.insertStats(StatsEntity(null, "STAT3"))
    var stat4 = characterStatsDao.insertStats(StatsEntity( null, "STAT4"))
    characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char1,stat1))
    characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char1,stat4))
    characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char2,stat2))
    characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char2,stat4))
    var charactersWithStatsList: List<CharacterWithStatsEntity> = characterStatsDao.getAllCharactersWithStats()

    for (cwsl: CharacterWithStatsEntity in charactersWithStatsList) {
        val currentChar  = cwsl.character
        for (se: StatsEntity in cwsl.stats) {
            Log.d("CWSLINFO","Character name is " + currentChar.name + " This stat is " + se.statsName)
        }
    }

Когда выполняется результат (т.е. значения statsName, получаемые через соединение): -

11-04 11:10:32.731 D/CWSLINFO: Character name is Fred This stat is STAT1
11-04 11:10:32.731 D/CWSLINFO: Character name is Fred This stat is STAT4
11-04 11:10:32.731 D/CWSLINFO: Character name is Mary This stat is STAT2
11-04 11:10:32.731 D/CWSLINFO: Character name is Mary This stat is STAT4

Если у таблицы соединений есть дополнительные значения, отличные от связей между таблицами, тогда я не верю, что другие значения могут быть получены напрямую, поскольку соединение предназначено для связи соединенных таблиц.

Однако такие значения можно получить, например, примите во внимание: -

  1. CharacterStatsEntity как

: -

@Entity(primaryKeys = ["characterIdReference","statsIdReference"])
data class CharacterStatsEntity (
    val characterIdReference: Long,
    val statsIdReference: Long,
    val otherValue: String //<<<<<<<<<< ADDED
)
Дополнительные Дао (1 из 2 будет достаточно)

: -

@Query("SELECT * FROM characterstatsentity WHERE characterIdReference = :characterId AND statsIdReference = :statsId")
fun getOtherValueFromJunction(characterId: Long, statsId: Long) :CharacterStatsEntity

@Query("SELECT otherValue FROM characterstatsentity WHERE characterIdReference = :characterId AND statsIdReference = :statsId")
fun getAltOtherValueFromJunction(characterId: Long, statsId: Long) :String

Изменение кода вызова

  1. Добавьте дополнительные данные, используя

: -

characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char1,stat1,"othervalue A"))
characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char1,stat4,"othervalue B"))
characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char2,stat2, "othervalue C"))
characterStatsDao.insertCharacterStatsJunction(CharacterStatsEntity(char2,stat4,"othervalue D"))
И цикл изменился, чтобы получить другие значения

: -

    for (cwsl: CharacterWithStatsEntity in charactersWithStatsList) {
        val currentChar  = cwsl.character
        for (se: StatsEntity in cwsl.stats) {
            Log.d("CWSLINFO",
                "Character name is " + currentChar.name +
                        " This stat is " + se.statsName +
                        " OV = " + characterStatsDao.getOtherValueFromJunction(currentChar.characterId!!,se.statsId!!).otherValue +
                        " ALTOV = " + characterStatsDao.getAltOtherValueFromJunction(cwsl.character.characterId!!,se.statsId!!)
            )
        }
    }

Результат будет:

2019-11-13 10:30:22.298 D/CWSLINFO: Character name is Fred This stat is STAT1 OV = othervalue A ALTOV = othervalue A
2019-11-13 10:30:22.300 D/CWSLINFO: Character name is Fred This stat is STAT4 OV = othervalue B ALTOV = othervalue B
2019-11-13 10:30:22.302 D/CWSLINFO: Character name is Mary This stat is STAT2 OV = othervalue C ALTOV = othervalue C
2019-11-13 10:30:22.304 D/CWSLINFO: Character name is Mary This stat is STAT4 OV = othervalue D ALTOV = othervalue D
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...