2017-07-12 20 views
8

चलो कहते हैं कि मैं एक INNER JOIN दोनों के बीच संस्थाओं Foo और Bar क्या करना चाहते हैं:वापसी प्रकार मिलती

@Query("SELECT * FROM Foo INNER JOIN Bar ON Foo.bar = Bar.id") 
List<FooAndBar> findAllFooAndBar(); 

वह इस तरह का वापसी प्रकार मजबूर करने के लिए संभव है?

public class FooAndBar { 
    Foo foo; 
    Bar bar; 
} 

जब मैं उस में, मैं इस त्रुटि मिलती है करने की कोशिश:

error: Cannot figure out how to read this field from a cursor. 

मैं भी क्षेत्र नाम से मेल करने तालिका नाम aliasing की कोशिश की है, लेकिन है कि या तो काम नहीं किया।

यदि यह संभव नहीं है, तो मुझे एक संगत रिटर्न प्रकार को कैसे साफ करना चाहिए जिसमें दोनों इकाइयों के लिए सभी फ़ील्ड शामिल हों?

उत्तर

1

Is it possible to force a return type like this?

आप foo और bar पर @Embedded एनोटेशन कोशिश कर सकते हैं। इससे कक्ष आपकी क्वेरी से कॉलम लेने का प्रयास करेगा और उन्हें foo और bar उदाहरणों में डालेगा। मैंने केवल इकाइयों के साथ यह कोशिश की है, लेकिन दस्तावेज़ों से संकेत मिलता है कि इसे पीओजेओ के साथ भी काम करना चाहिए।

हालांकि, यदि आपके दो तालिकाओं में समान नाम वाले कॉलम हैं तो यह ठीक से काम नहीं कर सकता है।

+0

हाँ, के बाद से मेरी संस्थाओं (जैसे 'id') ... – pqvst

+0

@pqvst इस नाम के कॉलम है कि काम नहीं करता है:" मैं कैसे सफाई से एक संगत निर्माण करना चाहिए वापसी प्रकार जिसमें दोनों संस्थाओं के लिए सभी फ़ील्ड शामिल हैं? " - या तो 'foo' या' bar' को '@ एम्बेडेड' होने के लिए चुनें और शेष फ़ील्ड सीधे 'FooAndBar' में रखें, या सभी फ़ील्ड सीधे 'FooAndBar' में रखें। परिणाम सेट में डुप्लिकेट कॉलम का नाम बदलने के लिए एसक्यूएल में 'AS' का उपयोग करें, और उन' AS' नामित कॉलम को मैप करने के लिए आवश्यकतानुसार '@ कॉलमइन्फो' का उपयोग करें, जिन्हें आप फ़ील्ड चाहते हैं। – CommonsWare

+0

यही वही है जो मैं करना चाहता हूं ...मुझे बहुत "साफ" महसूस नहीं होता है:/ – pqvst

8

दाव

@Query("SELECT * FROM Foo") 
List<FooAndBar> findAllFooAndBar(); 

कक्षा FooAndBar

public class FooAndBar { 
     @Embedded 
     Foo foo; 

     @Relation(parentColumn = "Foo.bar_id", entityColumn = "Bar.id") 
     //Relation returns a list 
     //Even if we only want a single Bar object .. 
     List<Bar> bar; 

     //Getter and setter... 
    } 

यह समाधान काम करने के लिए लगता है, लेकिन मैं इसके बारे में बहुत गर्व नहीं कर रहा हूँ। आप इसके बारे में क्या सोचते हैं?

संपादित करें: एक अन्य समाधान

दाव, मैं स्पष्ट चयन करना पसंद करते हैं, लेकिन "*" काम :)

@Query("SELECT Foo.*, Bar.* FROM Foo INNER JOIN Bar ON Foo.bar = Bar.id") 
List<FooAndBar> findAllFooAndBar(); 

कक्षा FooAndBar

public class FooAndBar { 
     @Embedded 
     Foo foo; 

     @Embedded 
     Bar bar; 

     //Getter and setter... 
    } 
+0

यदि 'फू' और 'बार' के बीच संघर्ष हैं, तो मेरा मानना ​​है कि आप बाद के वर्ग का सबसेट प्रतिनिधित्व बनाकर इन्हें खत्म कर सकते हैं, उदा। 'पब्लिक क्लास बेयरबार {... कुछ बार फ़ील्ड ...}', और फिर 'इकाई = BareBar.class' को '@ रिलेशनशिप' में जोड़ना। देखें: https://developer.android.com/reference/android/arch/persistence/room/Relation.html – AjahnCharles

1

एक अन्य विकल्प है अपनी जॉइन क्वेरी की परिणामी संरचना का प्रतिनिधित्व करने वाला एक नया POJO लिखने के लिए (जो संघर्ष से बचने के लिए कॉलम नामकरण का भी समर्थन करता है):

@Dao 
public interface FooBarDao { 
    @Query("SELECT foo.field1 AS unique1, bar.field1 AS unique2 " 
      + "FROM Foo INNER JOIN Bar ON Foo.bar = Bar.id") 
    public List<FooBar> getFooBars(); 

    static class FooBar { 
     public String unique1; 
     public String unique2; 
    } 
}  

देखें: room/accessing-data.html#query-multiple-tables

+1

यह तब काम करता है जब फ़ील्ड के समान नाम होते हैं, बस उनके लिए उपनाम होना चाहिए। –

संबंधित मुद्दे