我有3个表ruser,accounts,accountgroup。每个人都有一个称为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.
我试图为每个嵌入式对象添加一个前缀,但是我也遇到了一个错误。我不想一一检索列,因为它们很多。 有什么我想念的吗... ?? 谢谢
答案 0 :(得分:1)
或者,您可以使用嵌入式注释的prefix attribute:
class GroupChatItem(
@Embedded(prefix = "user_")
val rUserDto: RUserDto,
@Embedded(prefix = "acc_")
val account: AccountDto,
@Embedded(prefix = "accgr_")
val accountGroup: AccountGroupDto
)
,然后为SQL查询中每个实体的所有列加上别名。
我认为prefix属性是s最近的更新,但我不确定
答案 1 :(得分:0)
除了拥有/使用以外,我不相信您还有其他选择:-
或
我相信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")
这用于在游标(也称为结果集)中搜索列的名称,并将偏移量返回到该列,然后使用索引从游标中获取实际值。
在您的方案中,结果集将包含类似
的内容它应用于哪一个?您可能知道/理解第一个是ruser.rUserId,第二个是account.rUserId,第三个是accountgroup.rUserId,但就目前而言,Room在生成代码时将不知道。因此,在使用getColumnIndex("rUserId")
的所有3种情况下,它都会返回0(第一个)它退出循环,或者返回2(如果它继续而不是退出循环(我相信它不会中断)跳出循环)。