2014-10-05 26 views
7

Tôi hiện đang sử dụng ActiveAndroid và đã cố gắng có mối quan hệ nhiều người để làm việc trong vài giờ qua, tuy nhiên tôi không thể làm việc đó. Tôi hy vọng bạn có thể giúp tôi:ActiveAndroid Mối quan hệ nhiều-nhiều

Tôi có mô hình “Sinh viên” và “Khóa học”, sinh viên có thể có nhiều khóa học và khóa học có nhiều sinh viên. Về cơ bản đây là những gì tôi có trong mô hình “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"); 
} 

Ngay bây giờ những gì tôi đang cố gắng để làm là nhận được “tất cả học sinh trong khóa học X”, với đoạn mã sau:

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

Tuy nhiên tôi nhận được lỗi sau:

java.lang.ClassCastException: com.papinotas.models.StudentCourse không thể được đúc để com.papinotas.models.Student

Nếu tôi thay đổi o cast f (Học sinh) đến (StudentCourse) Tôi nhận được lỗi sau:

android.database.sqlite.SQLiteException: không có cột đó: student.StudentCourse (mã 1):, trong khi biên dịch: CHỌN * TỪ học sinh WHERE students.StudentCourse = 1

Mục tiêu chính của tôi là hy vọng đạt được điều này chỉ trong 1 truy vấn. Mọi sự trợ giúp sẽ rất được trân trọng. Cảm ơn trước!

PS: Tôi đã nhìn khá nhiều tất cả mọi thứ tôi có thể tìm thấy: Active Android many-to-many relationshiphttps://github.com/pardom/ActiveAndroid/issues/46

Trả lời

12

tôi sẽ không sử dụng getMany cho việc này.Tôi muốn làm điều này thay vì:

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

Dàn diễn viên nên thực sự là để (List<StudentCourse>), nhưng vấn đề thực sự là trong logic của mô hình của bạn ở đây. Bạn đang gọi executeSingle(), nhưng bạn thực sự muốn có nhiều đối tượng StudentCourse để bạn có được mọi mối quan hệ Student-Course cho Course. Các sinh viên() và các khóa học() của bạn không có ý nghĩa gì nhiều, vì một đối tượng StudentCourse chỉ có một Sinh viên và một Khóa học.

tôi sẽ làm điều đó như vậy thay vì:

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

Tôi đã cố gắng tìm một cách để có được tất cả các sinh viên với một truy vấn duy nhất; điều này sẽ làm N truy vấn nếu tôi không nhầm PS: Tôi hiểu điểm của bạn là gì, và tôi đồng ý nó không có ý nghĩa gì cả, tôi đã cố gắng làm theo ví dụ trên các liên kết tôi đã đăng ở trên, tuy nhiên họ đã không làm như vậy ' Tôi làm việc như tôi mong đợi. – Waclock

+0

Đây là một truy vấn SELECT duy nhất, nhưng sau đó nó thực hiện một số thao tác trong danh sách để bạn có được danh sách các sinh viên thay vì danh sách StudentCourses. –

+0

Ồ, "enrolment.student" không tạo ra một truy vấn tới cơ sở dữ liệu, vậy thì bạn nói đúng! – Waclock

1

làm việc như một nét duyên dáng:

lớp khách hàng

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

lớp Hợp đồng

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

Mối quan hệ giữa Chủ đầu tư và Hợp đồng

@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; 
} 

Cơ sở dữ liệu helper

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(); 
    } 
} 
Các vấn đề liên quan