2015-11-11 14 views
17

Sto costruendo un'app per Android con il database di Realm.Realm su Android - Come selezionare più oggetti per elenco di id (@PrimaryKey)?

Ho un RealmObject sottoclasse chiamato Article che ha un id campo (è e int e anche un @PrimaryKey). Vorrei passare a una query un elenco di int s (a Set, int[] o qualsiasi altra) di ID articolo e recuperare solo quegli articoli.

In SQL sarebbe come questo:

SELECT * 
FROM `table` 
where ID in (5263, 5625, 5628, 5621) 

ho visto che è possibile farlo in iOS in this StackOverflow question.

Come posso fare questo in Android? Grazie!

Modifica: Solo per informare, ho anche chiesto questo sul repository GitHub here.

+0

Questa domanda è stata molto simile: http://stackoverflow.com/a/32068221/2413303 – EpicPandaForce

+0

@EpicPandaForce Sì, è esattamente lo stesso.Ho cercato molto prima di postare però. La mia soluzione (sotto) gestisce il caso in cui la lista di id è vuota. –

+0

Ho aggiunto la parola "lista" al titolo della domanda. Forse renderà più facile trovare e capire qual è l'obiettivo. –

risposta

22

Aggiornamento:

Realm 1.2.0 ha aggiunto RealmQuery.in() per un confronto con più valori. The documentation descrive tutti i sovraccarichi disponibili. This one è il metodo che possiamo usare se le nostre ID sono Integer s:

public RealmQuery<E> in(String fieldName, Integer[] values) 

risposta originale:

La risposta da @ChristianMelchior restituisce tutti gli articoli se l'elenco di ID è vuoto. Voglio che restituisca un RealmResults<Article> vuoto. Questo è quello che ho finito per fare;

Set<Integer> articleIds = this.getArticleIds(); 
RealmQuery<Article> query = realm.where(Article.class); 
if (articleIds.size() == 0) { 
    // We want to return an empty list if the list of ids is empty. 
    // Just search for an id that does not exist. 
    query = query.equalTo("id", -30000); 
} else { 
    int i = 0; 
    for (int id : articleIds) { 
     // The or() operator requires left hand and right hand elements. 
     // If articleIds had only one element then it would crash with 
     // "Missing right-hand side of OR" 
     if (i++ > 0) { 
      query = query.or(); 
     } 
     query = query.equalTo("id", id); 
    } 
} 
return query.findAll(); 
+2

Quel momento imbarazzante in cui rispondi è migliore di quello del ragazzo che lavora in Reame. Grazie, ho pensato di creare qualcosa di simile a questo, ma speravo che il Realm avesse già un modo per farlo. Apparentemente non ... – AndreiBogdan

+0

puoi semplificare il codice rimuovendo l'i, usando semplicemente '' 'for (int pos = 0; pos 0) ... '' 'ovviamente il risultato sarà lo stesso, salverai solo la creazione int i e la creazione int id (ne creerà una nuova per ogni ID articolo), solo dicendo, perchè tutti stanno impazzendo per" memoria perdite "così ... ogni bit può avere importanza ^^ – user2582318

3

Le API Realm Java non lo supportano ancora sfortunatamente. È possibile seguire la richiesta di funzionalità qui https://github.com/realm/realm-java/issues/841

Il work-around attuale sarebbe quello di costruire la query se stessi in un ciclo for:

RealmResults<Article> articles = realm.allObjects(Article.class); 
RealmQuery q = articles.where(); 
for (int id : ids) { 
    q = q.equalTo("id", id); 
} 
RealmResults<Article> filteredArticles = q.findAll(); 
+0

Grazie a @ChristianMelchior. Il problema con questa risposta è che restituisce tutti gli articoli se la lista di id è vuota. Secondo me dovrebbe restituire un 'RealmResults

vuoto. Potrei aggiungere un'istruzione 'if' e controllare se' ids' è vuoto, ma non ho trovato alcun modo per creare un 'RealmResults
' vuoto. Sai come? –

+0

A seconda di cosa si sta facendo con RealmResults. Implementa l'interfaccia List in modo da poter creare semplicemente un ArrayList vuoto e utilizzarlo. Attualmente non è possibile creare manualmente un RealmResults vuoto. –

+3

2 cose: il metodo 'equalsTo()' (con una 's') non esiste (almeno non su 0.84.1), e il tuo codice funziona solo quando c'è un elemento nella lista di id (hai bisogno di un 'o()'). Grazie comunque! –

0

Mi sono appena imbattuto in questo post e ho pensato di poter inserire il mio 2 centesimo su questo. Per quanto apprezzi Christian Melchior e le sue risposte, penso che in questo caso la sua risposta non funzioni (almeno nella versione attuale).

preferisco farlo in questo modo - io personalmente penso che sia più leggibile di risposta di Albert Vila:

List<String> listOfIds = [..]; 
RealmQuery<SomeClass> query = realm.where(SomeClass.class); 

boolean first = true; 
for (String id : listOfIds) { 
    if (!first) { 
     query.or(); 
    } else { 
     first = false; 
    } 
    query.equalTo("id", id); 
} 
RealmResults<SomeClass> results = query.findAll(); 
4

Ora regno v 1.2.0 il supporto RealmQuery.in() per un confronto con valori multipli.

2

Questo è il modo in cui lo fa Reame dal 1.2.0:

public RealmQuery<E> in(String fieldName, String[] values) { 
    if (values == null || values.length == 0) { 
     throw new IllegalArgumentException(EMPTY_VALUES); 
    } 
    beginGroup().equalTo(fieldName, values[0]); 
    for (int i = 1; i < values.length; i++) { 
     or().equalTo(fieldName, values[i]); 
    } 
    return endGroup(); 
} 

precedenza this è come ho fatto

Problemi correlati