Подтвердить что ты не робот

Могу ли я выполнить этот Android-запрос с помощью ContentResolver.query()? (ЛЕВЫЙ ПРИСОЕДИНЕНИЕ И СЛУЧАЙ)

Я хочу выполнить следующий запрос (в псевдокоде) на Android:

SELECT C.ID, C.NAME, CASE ISNULL(G.GROUPID,0) = 0 THEN 0 ELSE 1 END INGROUP
FROM CONTACTS C 
LEFT JOIN GROUPMEMBERSHIP G ON G.CONTACTID = C.ID AND G.GROUPID = ?

Я ищу, чтобы выбрать идентификатор и имя всех контактов в адресной книге системы, используя по умолчанию Контакты ContentProvider, а также 0/1, указывающее, является ли контакт членом группы ?.

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

Могу ли я сделать это со стандартным методом строковой проекции высокого уровня и ContentResolver.query()? Или такой запрос потребует копания в более прямом выполнении SQL?

4b9b3361

Ответ 1

Нет, вы не можете делать такие запросы с помощью метода ContentResolver.query(). Вам нужно будет написать что-то вроде этого:

SQLiteDatabase db = YourActivity.getDbHelper().getReadableDatabase();
String query = yourLongQuery;
Cursor c = db.rawQuery(query, null);
YourActivity.startManagingCursor(c);
c.setNotificationUri(YourActivity.getContentResolver(), YourContentProvider.CONTENT_URI);

Ответ 2

Изменить: Хорошо, так что это фактически не решает вопрос, потому что eidylon привязан к существующему ContentProvider, как упоминалось в их вопросе. Однако это касается того, как вы выполняете JOIN, если у вас есть источник ContentProvider и API. Поэтому я оставлю это для тех, кто хочет знать, как справиться с этим делом.


Это легко! Но неинтуитивный...:)

query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder)

Хорошо, так что такое URI? Как правило, у вас есть один URI для каждой таблицы.

content://com.example.coolapp.contacts обслуживает данные из вашей таблицы CONTACTS. content://com.example.coolapp.groupmembers обслуживает данные из вашей таблицы GROUPMEMBERSHIP.

Но URI - это просто строка. Используйте его, как вам нравится. Создайте блок кода в ContentProvider, который отвечает на content://com.example.coolapp.contacts_in_group. Внутри этого блока кода в ContentProvider вы можете получить необработанный доступ к вашей базе данных SQLite, неограниченной ограниченной моделью данных query(). Не стесняйтесь использовать его!

Определите свои поля выбора, как вам нравится. Им не нужно сопоставлять имена столбцов таблиц - сопоставьте их, как вам нужно, чтобы получить ваши параметры.

Определите вашу проекцию, как вам нужно. Она может содержать столбцы из обеих таблиц после объединения.

Бин, все готово. Google делает эту же модель внутри своего собственного кода. Посмотрите на API-интерфейс поставщика контактов - вы видите "bla.RawContact" и "bla.Contact" и т.д. Как URI контента. Каждый из них обслуживает данные из одной и той же таблицы в БД - разные URI просто предоставляют разные представления этой же таблицы!

Ответ 3

Вы не можете этого сделать, потому что ContentResolver имеет только один метод запроса:

    query(Uri uri, String[] projection, String selection, 
String[] selectionArgs, String sortOrder)

нет параметров для таблиц или предложений FROM.