2014-10-05 24 views
7

Obecnie używam ActiveAndroid, i próbuję uzyskać wiele do wielu relacji do pracy w ciągu ostatnich kilku godzin, jednak po prostu nie mogę go uruchomić. Mam nadzieję, że możesz mi pomóc:ActiveAndroid Wielu do wielu relacji

Mam modele "Student" i "Kurs", student może mieć wiele kursów, a kurs ma wielu studentów. Zasadniczo jest to, co mam w modelu „StudentCourse”:

@Column(name = COURSE) 
public Course course; 

@Column(name = STUDENT) 
public Student student; 

public StudentCourse(Student student, Course course) { 
super(); 
this.student = student; 
this.course = course; 
} 
// 
public StudentCourse(){ } 

public List<Course> courses(){ 
return getMany(Course.class, "StudentCourse"); 
} 
public List<Student> students(){ 
return getMany(Student.class, "StudentCourse"); 
} 

Teraz co próbuję zrobić, to „wszyscy studenci z biegiem X”, z następującym kodem:

((Student) new Select().from(StudentCourse.class).where("course = ?",selectedCourse.getId()).executeSingle()).students(); 

jednak pojawia się następujący błąd:

java.lang.ClassCastException: com.papinotas.models.StudentCourse nie mogą być oddane do com.papinotas.models.Student

Jeśli zmienię o plastikowymi f (Student) do (StudentCourse) Pojawia się następujący błąd:

android.database.sqlite.SQLiteException: brak takiej kolumny: students.StudentCourse (kod 1):, podczas kompilacji: SELECT * FROM studentów WHERE students.StudentCourse = 1

Moim głównym celem jest osiągnięcie tego w zaledwie jednym zapytaniu. Każda pomoc będzie bardzo ceniona. Z góry dziękuję!

PS: Ja już spojrzał na prawie wszystko udało mi się znaleźć: Active Android many-to-many relationship i https://github.com/pardom/ActiveAndroid/issues/46

Odpowiedz

12

Nie użyłbym getMany do tego.Chciałbym to zrobić w zamian:

return new Select() 
    .from(Student.class) 
    .innerJoin(StudentCourse.class).on("students.id = studentcourses.id") 
    .where("studentcourses.course = ?", courseId) 
    .execute(); 
1

If I change the cast of (Student) to (StudentCourse) I get the following error...

Obsada powinna być w rzeczywistości do (List<StudentCourse>), ale prawdziwym problemem jest w logice modelu tutaj. Wzywasz executeSingle(), ale naprawdę chcesz wielu obiektów StudentCourse, aby uzyskać wszystkie relacje Studenta z Kursem. Metody twoich studentów() i kursów() nie mają większego sensu, ponieważ jeden obiekt StudentCourse ma tylko jednego Studenta i jeden Kurs.

zrobiłbym to tak jakby zamiast:

List<StudentCourse> enrolments = new Select().from(StudentCourse.class).where("course = ?",selectedCourse.getId()).execute(); 

List<Student> studentsInCourse = new ArrayList<Student>(); 
for(StudentCourse enrolment:enrolments) 
    studentsInCourse.add(enrolment.student); 
+0

starałem się znaleźć sposób na zdobycie wszystkich studentów za pomocą pojedynczego zapytania; to zrobiłoby N zapytań, jeśli się nie mylę PS: Rozumiem, o co ci chodzi, i zgadzam się, że to nie ma sensu, próbowałem podążać za przykładem na linkach zamieszczonych powyżej, jednak nie zrobili tego ". działa tak, jak się spodziewałem. – Waclock

+0

To jest jedno zapytanie SELECT, ale potem robi trochę manipulacji Listą, dzięki czemu otrzymujesz listę Uczniów, a nie listę Kursów Studenckich. –

+0

Och, "enrolment.student" nie wysyła zapytania do bazy danych, to masz rację! – Waclock

1

działają jak zaklęcie:

klasy Client

@Table(name = "Client") 
public class Client extends Model{} 

klasa kontraktu

@Table(name = "Contract") 
public class Contract extends Model{} 

Relacja pomiędzy Klientem Umowy i

@Table(name = "ClientContract") 
public class ClientContract extends Model { 

    @Column(name = "Client", onDelete = Column.ForeignKeyAction.CASCADE) 
    public Client client; 

    @Column(name = "Contract", onDelete = Column.ForeignKeyAction.CASCADE) 
    public Contract contract; 
} 

pomocnik Database

public class DBHelper { 

public List<Contract> getRelatedContracts(Client client) { 
     List<Contract> contracts = null; 

     if (client != null && client.isCreated()) { 
      contracts = new Select() 
        .from(Contract.class) 
        .innerJoin(ClientContract.class).on("ClientContract.Contract = Contract.id") 
        .where("ClientContract.Client = ?", client.getId()) 
        .execute(); 
     } 
     return contracts; 
    } 

    public List<Client> getRelatedClients(Contract contract) { 
     List<Client> clients = null; 

     if (contract != null && contract.isCreated()) { 
      clients = new Select() 
        .from(Client.class) 
        .innerJoin(ClientContract.class).on("ClientContract.Client = Client.id") 
        .where("ClientContract.Contract = ?", contract.getId()) 
        .execute(); 
     } 
     return clients; 
    } 

    // get relation 
    public ClientContract getClientContract(Client client, Contract contract) { 
     ClientContract clientContract = null; 
     if (client != null && contract != null && client.isCreated() && contract.isCreated()) { 

      clientContract = new Select().from(ClientContract.class) 
        .where("Client = ?", client.getId()) 
        .where("Contract = ?", contract.getId()) 
        .executeSingle(); 
     } 
     return clientContract; 
    } 

    // add relation 
    public ClientContract addClientContract(Client client, Contract contract) { 
     ClientContract clientContract = getClientContract(client, contract); 

     if (client != null && contract != null && clientContract == null) { 

      if (client.getId() == null) 
       client.save(); 

      if (contract.getId() == null) 
       contract.save(); 

      clientContract = new ClientContract(); 
      clientContract.client = client; 
      clientContract.contract = contract; 
      clientContract.save(); 

     } 
     return clientContract; 
    } 

    // delete relation 
    public void deleteClientContract(Client client, Contract contract) { 
     ClientContract clientContract = getClientContract(client, contract); 
     if (clientContract != null && contract.isCreated()) 
      clientContract.delete(); 
    } 
} 
Powiązane problemy