我有3个表ruser,帐户,帐户组。每个人都有一个称为rsuerId的同一列。

我创建了一个带有3个嵌入式对象的POJO类,如下所示。

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


现在,我想进行如下查询,该查询使用给定的rUserId和accountGroupId来获取GroupChatItem,如下所示。

@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.


我试图为每个嵌入式对象添加一个前缀,但是我也遇到了一个错误。我不想一一检索列,因为它们很多。
有什么我想念的吗... ??
谢谢

最佳答案

我不相信您除了拥有/使用之外别无选择:


a)在要包含在联接中的表中具有不同的列名(因此,无需在列名前添加前缀),


要么


b)提取值时,应使用AS重命名列,并在嵌入实体时确保其名称匹配时使用前缀。


我相信a)将是更简单的选择,因为这样会减少无意中使用错误的列名的可能性。



据我了解,列名称必须与Room匹配,才能知道如何能够从基础结果集中复制值,而这并不能指示值是从哪个表中返回的对象中的值或对象。

这是类似情况3嵌入式实体(用户,办公室和位置)的生成代码的示例,其中某些列名称相同。它们每个都有一个id列,而User和Places都有一个名为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不会在生成代码时知道。因此,在使用getColumnIndex("rUserId")的所有3种情况下,它都会返回0(第一个)它退出循环,或者返回2(如果它继续而不是退出循环)(我相信它不会退出循环)循环)。

10-08 02:07