Definieren Sie eine Eins-zu-Viele-Beziehung zwischen Raumentitäten für das Chat-Modell

8

Ich begann mit der Verwendung der Raumdatenbank und ging mehrere Dokumente durch, um Raumentitäten zu erstellen. Das sind meine Verwandten. Ein Chat-Kanal kann viele Gespräche führen. Das ist also eine Eins-zu-Viele-Beziehung. Daher habe ich Entitäten wie folgt erstellt.

Kanalentität

@Entity(primaryKeys = ["channelId"])
@TypeConverters(TypeConverters::class)
data class Channel(
    @field:SerializedName("channelId")
    val channelId: String,
    @field:SerializedName("channelName")
    val channelName: String,
    @field:SerializedName("createdBy")
    val creationTs: String,
    @field:SerializedName("creationTs")
    val createdBy: String,
    @field:SerializedName("members")
    val members: List<String>,
    @field:SerializedName("favMembers")
    val favMembers: List<String>
) {
  // Does not show up in the response but set in post processing.
  var isOneToOneChat: Boolean = false
  var isChatBot: Boolean = false
}

Gesprächseinheit

@Entity(primaryKeys = ["msgId"],
    foreignKeys = [
        ForeignKey(entity = Channel::class,
                parentColumns = arrayOf("channelId"),
                childColumns = arrayOf("msgId"),
                onUpdate = CASCADE,
                onDelete = CASCADE
        )
    ])
@TypeConverters(TypeConverters::class)
data class Conversation(

    @field:SerializedName("msgId")
    val msgId: String,
    @field:SerializedName("employeeID")
    val employeeID: String,
    @field:SerializedName("channelId")
    val channelId: String,
    @field:SerializedName("channelName")
    val channelName: String,
    @field:SerializedName("sender")
    val sender: String,
    @field:SerializedName("sentAt")
    val sentAt: String,
    @field:SerializedName("senderName")
    val senderName: String,
    @field:SerializedName("status")
    val status: String,
    @field:SerializedName("msgType")
    val msgType: String,
    @field:SerializedName("type")
    val panicType: String?,
    @field:SerializedName("message")
    val message: List<Message>,
    @field:SerializedName("deliveredTo")
    val delivered: List<Delivered>?,
    @field:SerializedName("readBy")
    val read: List<Read>?

) {

data class Message(
        @field:SerializedName("txt")
        val txt: String,
        @field:SerializedName("lang")
        val lang: String,
        @field:SerializedName("trans")
        val trans: String
)

data class Delivered(
        @field:SerializedName("employeeID")
        val employeeID: String,
        @field:SerializedName("date")
        val date: String
)

data class Read(
        @field:SerializedName("employeeID")
        val employeeID: String,
        @field:SerializedName("date")
        val date: String
)

    // Does not show up in the response but set in post processing.
    var isHeaderView: Boolean = false
}

Wie Sie jetzt sehen können, gehört Conversation zu einem Kanal . Wenn der Benutzer eine Liste von Kanälen sieht, muss ich mehrere Attribute der letzten Konversation im Listenelement anzeigen . Meine Frage ist, ist es genug, wenn ich nur eine Beziehung wie oben deklariere oder sollte ich ein Converstion-Objekt in der Channel-Klasse enthalten? Was sind die anderen Möglichkeiten, wie ich damit umgehen kann? Weil die Benutzeroberfläche die neuesten Konversationen erhalten muss, die zusammen mit der Zeit, dem Status usw. in jedem Element der Kanalliste stattgefunden haben, wenn der Benutzer einen Bildlauf durchführt. Daher sollte es bei der Abfrage keine Verzögerung in der Benutzeroberfläche geben.

Und wie kann ich das aktuelle Converstaion-Objekt im Channel-Objekt haben?

androidbash
quelle

Antworten:

1

Ich schlage vor, eine andere Klasse (nicht in DB, nur zum Anzeigen in der Benutzeroberfläche) wie folgt zu erstellen:

data class LastConversationInChannel(
    val channelId: String,
    val channelName: String,
    val creationTs: String,
    val createdBy: String,
    val msgId: String,
    val employeeID: String,
    val sender: String,
    val sentAt: String,
    val senderName: String
    .
    .
    .
)

Holen Sie sich die letzte Konversation in jedem Kanal durch diese Abfrage:

 SELECT Channel.*
 ,IFNULL(LastConversation.msgId,'') msgId
 ,IFNULL(LastConversation.sender,'') sender
 ,IFNULL(LastConversation.employeeID,'') employeeID
 ,IFNULL(LastConversation.sentAt,'') sentAt
 ,IFNULL(LastConversation.senderName,'') senderName
 from Channel left join 
 (SELECT * from Conversation a  
 WHERE a.msgId IN ( SELECT b.msgId  FROM Conversation AS b 
                    WHERE a.channelId = b.channelId 
                    ORDER BY b.sentAt DESC  LIMIT 1 )) as LastConversation
 on Channel.channelId = LastConversation.channelId

Verwenden Sie es dann in Ihrem Dao wie folgt:

 @Query(" SELECT Channel.*\n" +
            " ,IFNULL(LastConversation.msgId,'') msgId\n" +
            " ,IFNULL(LastConversation.sender,'') sender\n" +
            " ,IFNULL(LastConversation.employeeID,'') employeeID\n" +
            " ,IFNULL(LastConversation.sentAt,'') sentAt\n" +
            " ,IFNULL(LastConversation.senderName,'') senderName\n" +
            " from Channel left join \n" +
            " (SELECT * from Conversation a  \n" +
            " WHERE a.msgId IN ( SELECT b.msgId  FROM Conversation AS b \n" +
            "                    WHERE a.channelId = b.channelId \n" +
            "                    ORDER BY b.sentAt DESC  LIMIT 1 )) as LastConversation\n" +
            " on Channel.channelId = LastConversation.channelId")
    fun getLastConversationInChannel(): LiveData<List<LastConversationInChannel>>

Ist es genug, wenn ich nur eine Beziehung wie oben deklariere oder sollte ich ein Converstion-Objekt in der Channel-Klasse enthalten?

Sie sollten Conversation nicht in der Channel-Klasse enthalten, da Room in der Conversation-Tabelle einige Spalten dafür erstellt.

Iman Hamidi
quelle
0

Sie können eine haben, LastConversationdie eine Conversation objectim Chanel ist. Sie müssen dies jedes Mal aktualisieren, wenn die letzte Konversation aktualisiert wird, indem Sie die Tabelle Chanel aus der Raumebene ändern. (Nehmen Sie nicht so viel Leistung für Update-Datenbank). Durch Implementieren der Sortierung für die Chanel-Liste (Vergleichbar). Ihr UI-Update wird cool sein. Und Ihre Logik von UI oder ViewModel ist einfacher. Ich habe es auch so gemacht.

Thành Hà Văn
quelle