تعریف و پُرسمان روابط یک‌به‌چند

رابطه یک به چند بین دو نهاد رابطه‌ای است که در آن هر نمونه از نهاد والد با صفر یا چند نمونه از نهاد فرزند مطابقت دارد، اما هر نمونه از نهاد فرزند فقط می‌تواند با یک نمونه از نهاد والد مطابقت داشته باشد.

در مثال برنامه جاری‌سازی موسیقی، فرض کنید کاربر بتواند آهنگ‌هایش را در فهرست‌های پخش سازمان‌دهی کند. هر کاربر می‌تواند هر تعداد فهرست پخش که می‌خواهد ایجاد کند، اما هر فهرست پخش را دقیقاً یک کاربر ایجاد می‌کند. بنابراین، بین نهاد User و نهاد Playlist رابطه یک‌به‌چند وجود دارد.

برای تعریف و پُرسمان کردن روابط یک‌به‌چند در پایگاه داده‌تان، این مراحل را دنبال کنید:

  1. تعریف رابطه: کلاس‌هایی برای هر دو نهاد ایجاد کنید، با نهاد فرزند که به کلید اصلی ولی ارجاع می‌دهد.
  2. پرسش از نهادها: رابطه را در کلاس داده جدیدی مدل‌سازی کنید و تابعی برای بازیابی داده‌های مرتبط پیاده‌سازی کنید.

تعریف رابطه

برای تعریف رابطه یک‌به‌چند، ابتدا برای هر نهاد کلاسی ایجاد کنید. همانند رابطه یک‌به‌یک، نهاد فرزند باید شامل متغیری باشد که به کلید اصلی نهاد والد ارجاع می‌دهد.

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userCreatorId: Long,
    val playlistName: String
)

پُرسمان نهادها

برای پُرسمان کردن فهرست کاربران و فهرست‌های پخش مربوطه، ابتدا باید رابطه یک‌به‌چند بین دو نهاد را مدل کنید.

برای مدل‌سازی رابطه، کلاس داده جدیدی ایجاد کنید. هر نمونه از این کلاس شامل نمونه‌ای از نهاد والد و فهرستی از همه نمونه‌های نهاد فرزند مربوطه است. برچسب @Relation را به دارایی‌ای که نشان‌دهنده فهرست نهادهای فرزند است اضافه کنید. parentColumns را روی نام ستون کلید اصلی نهاد والد تنظیم کنید، و entityColumns را روی نام ستون نهاد فرزند که به کلید اصلی نهاد والد ارجاع می‌دهد تنظیم کنید.

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["userId"],
        entityColumns = ["userCreatorId"]
    )
    val playlists: List<Playlist>
)

درنهایت، تابعی به کلاس شیء دسترسی به داده (DAO) اضافه کنید که همه نمونه‌های کلاس داده را برمی‌گرداند و نهاد والد و نهاد فرزند را جفت می‌کند. حاشیه @Transaction را اضافه کنید تا Room کل عملیات را به‌صورت اتمی انجام دهد. این گزارمان ضروری است زیرا این تابع برای اجرای دو پُرسمان به Room نیاز دارد.

@Transaction
@Query("SELECT * FROM User")
suspend fun getUsersWithPlaylists(): List<UserWithPlaylists>

کلیدهای ترکیبی

اگر رابطه را بااستفاده از کلیدهای ترکیبی تعریف می‌کنید، چندین ستون را در parentColumns و entityColumns مشخص کنید. ترتیب ستون‌ها در parentColumns باید با ترتیب ستون‌ها در entityColumns مطابقت داشته باشد.

@Entity(primaryKeys = ["firstName", "lastName"])
data class User(
    val firstName: String,
    val lastName: String,
    val age: Int
)

@Entity
data class Playlist(
    @PrimaryKey val playlistId: Long,
    val userFirstName: String,
    val userLastName: String,
    val playlistName: String
)

data class UserWithPlaylists(
    @Embedded val user: User,
    @Relation(
        parentColumns = ["firstName", "lastName"],
        entityColumns = ["userFirstName", "userLastName"]
    )
    val playlists: List<Playlist>
)