Несколько полей имеют одинаковый столбец Имя Android Room - PullRequest
0 голосов
/ 16 октября 2019

У меня 3 таблицы ruser, account, accountgroup. Каждый из них имеет один и тот же столбец с именем rsuerId.

Я создал класс POJO с 3 встроенными объектами, как показано ниже.

class GroupChatItem(
    @Embedded
    val rUserDto: RUserDto,
    @Embedded
    val account: AccountDto,
    @Embedded
    val accountGroup: AccountGroupDto
)

Теперь я хочу сделать запрос, который выбирает GroupChatItem сучитывая rUserId и accountGroupId, как показано ниже.

@Query("""
        Select ruser.*, accounts.*, accountgroup.*
        from ruser 
        inner join accounts on accounts.rUserId = ruser.rUserId and accounts.active = 1 
        inner join accountgroup on accountgroup.rUserId = :rUserId and accountGroup.accountGroupId = :accountGroupId
        where ruser.rUserId = :rUserId
    """)
    suspend fun getGroupChatItem(rUserId: Long, accountGroupId: Int): GroupChatItem

К сожалению, я получаю следующую ошибку.

 Multiple fields have the same columnName: rUserId. Field names: rUserDto > rUserId, account > rUserId, accountGroup > rUserId.

Я попытался добавить префикс для каждого встроенного объекта, но я также получаю ошибку,Я не хочу получать столбцы один за другим, потому что их много. Есть что-то, что я пропустил ... ?? Спасибо

1 Ответ

0 голосов
/ 16 октября 2019

Я не думаю, что у вас есть какой-либо вариант, кроме как иметь / использовать: -

  • a) иметь разные имена столбцов в таблицах, которые должны быть включены в объединения (тогда нетнеобходимо префиксировать имена столбцов),

или

  • b), чтобы переименовать столбцы, используя AS при извлечении значений вместе с префиксом при встраивании объекта, гарантируя, чтоимена совпадают.

Я полагаю, что a) будет более простым вариантом, поскольку уменьшается вероятность непреднамеренного использования неправильного имени столбца.


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

Это пример сгенерированного кода по аналогичному сценарию 3 встроенных объекта ( Пользователь , Офис и Места ), где некоторые изстолбец намес одинаковы. У каждого из них есть и id столбец, а у пользователя и места есть столбцы с именем name .

@Override
public UserOfficePlacesCombined getAllUserOfficePlacesCombined() {
    final String _sql = "SELECT user.id AS userid, user.name AS username, office.id AS officeid, office.address AS officeaddress, places.id AS placesid, places.name AS placesname FROM User JOIN Office ON User.id = Office.id JOIN Places ON User.id = Places.id";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
        final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "userid");
        final int _cursorIndexOfName = CursorUtil.getColumnIndexOrThrow(_cursor, "username");
        final int _cursorIndexOfId_1 = CursorUtil.getColumnIndexOrThrow(_cursor, "officeid");
        final int _cursorIndexOfAddress = CursorUtil.getColumnIndexOrThrow(_cursor, "officeaddress");
        final int _cursorIndexOfId_2 = CursorUtil.getColumnIndexOrThrow(_cursor, "placesid");
        final int _cursorIndexOfName_1 = CursorUtil.getColumnIndexOrThrow(_cursor, "placesname");
        final UserOfficePlacesCombined _result;
        if(_cursor.moveToFirst()) {
            final User _tmpUser;
            if (! (_cursor.isNull(_cursorIndexOfId) && _cursor.isNull(_cursorIndexOfName))) {
                final long _tmpId;
                _tmpId = _cursor.getLong(_cursorIndexOfId);
                final String _tmpName;
                _tmpName = _cursor.getString(_cursorIndexOfName);
                _tmpUser = new User(_tmpId,_tmpName);
            }  else  {
                _tmpUser = null;
            }
            final Office _tmpOffice;
            if (! (_cursor.isNull(_cursorIndexOfId_1) && _cursor.isNull(_cursorIndexOfAddress))) {
                final long _tmpId_1;
                _tmpId_1 = _cursor.getLong(_cursorIndexOfId_1);
                final String _tmpAddress;
                _tmpAddress = _cursor.getString(_cursorIndexOfAddress);
                _tmpOffice = new Office(_tmpId_1,_tmpAddress);
            }  else  {
                _tmpOffice = null;
            }
            final Places _tmpPlaces;
            if (! (_cursor.isNull(_cursorIndexOfId_2) && _cursor.isNull(_cursorIndexOfName_1))) {
                final long _tmpId_2;
                _tmpId_2 = _cursor.getLong(_cursorIndexOfId_2);
                final String _tmpName_1;
                _tmpName_1 = _cursor.getString(_cursorIndexOfName_1);
                _tmpPlaces = new Places(_tmpId_2,_tmpName_1);
            }  else  {
                _tmpPlaces = null;
            }
            _result = new UserOfficePlacesCombined();
            _result.setUser(_tmpUser);
            _result.setOffice(_tmpOffice);
            _result.setPlaces(_tmpPlaces);
        } else {
            _result = null;
        }
        return _result;
    } finally {
        _cursor.close();
        _statement.release();
    }
}

Критические строки, такие как: -

 final int _cursorIndexOfId = CursorUtil.getColumnIndexOrThrow(_cursor, "userid")

Используется для поиска имен столбцов в Курсоре (он же набор результатов) и возврата смещения к столбцу, индекс затем используется для получения фактического значения из Курсора.

В вашем сценарии набор результатов будет включать примерно такие, как

  • rUserId rUserId rUserId *

Какой из них следует использовать для каких? Вы можете знать / понимать, что первым является ruser.rUserId, а вторым - account.rUserId, а третьим - accountgroup.rUserId, но Room, в его нынешнем виде, не будет знать при создании кода. Таким образом, во всех 3 случаях, когда используется getColumnIndex("rUserId"), он вернет либо 0 (первый), который он прерывает из цикла, либо 2, если он продолжается, а не выходит из цикла (я считаю, что он не выходит из цикла). петля).

...