Hubungan, properti navigasi, dan kunci asing
Artikel ini memberikan gambaran umum tentang bagaimana Kerangka Kerja Entitas mengelola hubungan antar entitas. Ini juga memberikan beberapa panduan tentang cara memetakan dan memanipulasi hubungan.
Hubungan dalam EF
Dalam database relasional, hubungan (juga disebut asosiasi) antara tabel didefinisikan melalui kunci asing. Kunci asing (FK) adalah kolom atau kombinasi kolom yang digunakan untuk membuat dan menerapkan tautan antara data dalam dua tabel. Umumnya ada tiga jenis hubungan: satu-ke-satu, satu-ke-banyak, dan banyak-ke-banyak. Dalam hubungan satu ke banyak, kunci asing didefinisikan pada tabel yang mewakili banyak akhir hubungan. Hubungan banyak ke banyak melibatkan penentuan tabel ketiga (disebut persimpangan atau tabel gabungan), yang kunci utamanya terdiri dari kunci asing dari kedua tabel terkait. Dalam hubungan satu-ke-satu, kunci utama bertindak juga sebagai kunci asing dan tidak ada kolom kunci asing terpisah untuk salah satu tabel.
Gambar berikut menunjukkan dua tabel yang berpartisipasi dalam hubungan satu ke banyak. Tabel Kursus adalah tabel dependen karena berisi kolom DepartmentID yang menautkannya ke tabel Departemen .
Dalam Kerangka Kerja Entitas, entitas dapat terkait dengan entitas lain melalui asosiasi atau hubungan. Setiap hubungan berisi dua ujung yang menjelaskan jenis entitas dan perkalian jenis (satu, nol atau satu, atau banyak) untuk dua entitas dalam hubungan tersebut. Hubungan dapat diatur oleh batasan referensial, yang menjelaskan mana yang berakhir dalam hubungan adalah peran utama dan yang merupakan peran dependen.
Properti navigasi menyediakan cara untuk menavigasi asosiasi antara dua jenis entitas. Setiap objek dapat memiliki properti navigasi untuk setiap hubungan tempat objek berpartisipasi. Properti navigasi memungkinkan Anda menavigasi dan mengelola hubungan di kedua arah, mengembalikan objek referensi (jika perkalian adalah satu atau nol-atau-satu) atau koleksi (jika perkaliannya banyak). Anda juga dapat memilih untuk memiliki navigasi satu arah, dalam hal ini Anda menentukan properti navigasi hanya pada salah satu jenis yang berpartisipasi dalam hubungan dan bukan pada keduanya.
Disarankan untuk menyertakan properti dalam model yang memetakan ke kunci asing dalam database. Dengan termasuk properti kunci asing, Anda dapat membuat atau mengubah hubungan dengan memodifikasi nilai kunci asing pada objek dependen. Asosiasi semacam ini disebut asosiasi kunci asing. Menggunakan kunci asing bahkan lebih penting ketika bekerja dengan entitas yang terputus. Perhatikan bahwa saat bekerja dengan 1-ke-1 atau 1-ke-0.. 1 hubungan, tidak ada kolom kunci asing terpisah, properti kunci utama bertindak sebagai kunci asing dan selalu disertakan dalam model.
Ketika kolom kunci asing tidak disertakan dalam model, informasi asosiasi dikelola sebagai objek independen. Hubungan dilacak melalui referensi objek alih-alih properti kunci asing. Jenis asosiasi ini disebut asosiasi independen. Cara paling umum untuk memodifikasi asosiasi independen adalah dengan memodifikasi properti navigasi yang dihasilkan untuk setiap entitas yang berpartisipasi dalam asosiasi.
Anda dapat memilih untuk menggunakan satu atau kedua jenis asosiasi dalam model Anda. Namun, jika Anda memiliki hubungan banyak-ke-banyak murni yang dihubungkan oleh tabel gabungan yang hanya berisi kunci asing, EF akan menggunakan asosiasi independen untuk mengelola hubungan banyak ke banyak tersebut.
Gambar berikut menunjukkan model konseptual yang dibuat dengan Perancang Kerangka Kerja Entitas. Model ini berisi dua entitas yang berpartisipasi dalam hubungan satu-ke-banyak. Kedua entitas memiliki properti navigasi. Kursus adalah entitas dependen dan memiliki properti kunci asing DepartmentID yang ditentukan.
Cuplikan kode berikut menunjukkan model yang sama yang dibuat dengan Code First.
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public int DepartmentID { get; set; }
public virtual Department Department { get; set; }
}
public class Department
{
public Department()
{
this.Courses = new HashSet<Course>();
}
public int DepartmentID { get; set; }
public string Name { get; set; }
public decimal Budget { get; set; }
public DateTime StartDate { get; set; }
public int? Administrator {get ; set; }
public virtual ICollection<Course> Courses { get; set; }
}
Mengonfigurasi atau memetakan hubungan
Sisa halaman ini mencakup cara mengakses dan memanipulasi data menggunakan hubungan. Untuk informasi tentang menyiapkan hubungan dalam model Anda, lihat halaman berikut ini.
- Untuk mengonfigurasi hubungan di Kode Pertama, lihat Anotasi Data dan API Fasih – Hubungan.
- Untuk mengonfigurasi hubungan menggunakan Perancang Kerangka Kerja Entitas, lihat Hubungan dengan Desainer EF.
Membuat dan memodifikasi hubungan
Dalam asosiasi kunci asing, ketika Anda mengubah hubungan, status objek dependen dengan status berubah menjadi EntityState.Unchanged
EntityState.Modified
. Dalam hubungan independen, mengubah hubungan tidak memperbarui status objek dependen.
Contoh berikut menunjukkan cara menggunakan properti kunci asing dan properti navigasi untuk mengaitkan objek terkait. Dengan asosiasi kunci asing, Anda dapat menggunakan salah satu metode untuk mengubah, membuat, atau memodifikasi hubungan. Dengan asosiasi independen, Anda tidak dapat menggunakan properti kunci asing.
Dengan menetapkan nilai baru ke properti kunci asing, seperti dalam contoh berikut.
course.DepartmentID = newCourse.DepartmentID;
Kode berikut menghapus hubungan dengan mengatur kunci asing ke null. Perhatikan, bahwa properti kunci asing harus nullable.
course.DepartmentID = null;
Catatan
Jika referensi dalam status ditambahkan (dalam contoh ini, objek kursus), properti navigasi referensi tidak akan disinkronkan dengan nilai kunci objek baru sampai SaveChanges dipanggil. Sinkronisasi tidak terjadi karena konteks objek tidak berisi kunci permanen untuk objek yang ditambahkan hingga disimpan. Jika Anda harus memiliki objek baru yang sepenuhnya disinkronkan segera setelah Anda mengatur hubungan, gunakan salah satu metode berikut.*
Dengan menetapkan objek baru ke properti navigasi. Kode berikut membuat hubungan antara kursus dan
department
. Jika objek dilampirkan ke konteks,course
juga ditambahkan kedepartment.Courses
koleksi, dan properti kunci asing yang sesuai padacourse
objek diatur ke nilai properti kunci departemen.course.Department = department;
Untuk menghapus hubungan, atur properti navigasi ke
null
. Jika Anda bekerja dengan Entity Framework yang didasarkan pada .NET 4.0, maka akhir terkait perlu dimuat sebelum Anda mengaturnya ke null. Contohnya:context.Entry(course).Reference(c => c.Department).Load(); course.Department = null;
Dimulai dengan Entity Framework 5.0, yang didasarkan pada .NET 4.5, Anda dapat mengatur hubungan ke null tanpa memuat akhir terkait. Anda juga dapat mengatur nilai saat ini ke null menggunakan metode berikut.
context.Entry(course).Reference(c => c.Department).CurrentValue = null;
Dengan menghapus atau menambahkan objek dalam kumpulan entitas. Misalnya, Anda dapat menambahkan objek jenis
Course
kedepartment.Courses
koleksi. Operasi ini menciptakan hubungan antara kursus tertentu dan tertentudepartment
. Jika objek dilampirkan ke konteks, referensi departemen dan properti kunci asing pada objek kursus akan diatur ke yang sesuaidepartment
.department.Courses.Add(newCourse);
Dengan menggunakan
ChangeRelationshipState
metode untuk mengubah status hubungan yang ditentukan antara dua objek entitas. Metode ini paling umum digunakan saat bekerja dengan aplikasi N-Tingkat dan asosiasi independen (tidak dapat digunakan dengan asosiasi kunci asing). Selain itu, untuk menggunakan metode ini, Anda harus turun keObjectContext
, seperti yang ditunjukkan pada contoh di bawah ini.
Dalam contoh berikut, ada hubungan banyak ke banyak antara Instruktur dan Kursus. MemanggilChangeRelationshipState
metode dan meneruskanEntityState.Added
parameter, memberiSchoolContext
tahu bahwa hubungan telah ditambahkan di antara dua objek:((IObjectContextAdapter)context).ObjectContext. ObjectStateManager. ChangeRelationshipState(course, instructor, c => c.Instructor, EntityState.Added);
Perhatikan bahwa jika Anda memperbarui (bukan hanya menambahkan) hubungan, Anda harus menghapus hubungan lama setelah menambahkan yang baru:
((IObjectContextAdapter)context).ObjectContext. ObjectStateManager. ChangeRelationshipState(course, oldInstructor, c => c.Instructor, EntityState.Deleted);
Menyinkronkan perubahan antara kunci asing dan properti navigasi
Saat Anda mengubah hubungan objek yang dilampirkan ke konteks dengan menggunakan salah satu metode yang dijelaskan di atas, Kerangka Kerja Entitas perlu menjaga kunci asing, referensi, dan koleksi tetap sinkron. Entity Framework secara otomatis mengelola sinkronisasi ini (juga dikenal sebagai perbaikan hubungan) untuk entitas POCO dengan proksi. Untuk informasi selengkapnya, lihat Bekerja dengan Proksi.
Jika Anda menggunakan entitas POCO tanpa proksi, Anda harus memastikan bahwa metode DetectChanges dipanggil untuk menyinkronkan objek terkait dalam konteks. Perhatikan bahwa API berikut secara otomatis memicu panggilan DetectChanges .
DbSet.Add
DbSet.AddRange
DbSet.Remove
DbSet.RemoveRange
DbSet.Find
DbSet.Local
DbContext.SaveChanges
DbSet.Attach
DbContext.GetValidationErrors
DbContext.Entry
DbChangeTracker.Entries
- Menjalankan kueri LINQ terhadap
DbSet
Memuat objek terkait
Dalam Kerangka Kerja Entitas, Anda biasanya menggunakan properti navigasi untuk memuat entitas yang terkait dengan entitas yang dikembalikan oleh asosiasi yang ditentukan. Untuk informasi selengkapnya, baca Memuat Objek Terkait.
Catatan
Dalam asosiasi kunci asing, ketika Anda memuat akhir terkait dari objek dependen, objek terkait akan dimuat berdasarkan nilai kunci asing dependen yang saat ini berada dalam memori:
// Get the course where currently DepartmentID = 2.
Course course = context.Courses.First(c => c.DepartmentID == 2);
// Use DepartmentID foreign key property
// to change the association.
course.DepartmentID = 3;
// Load the related Department where DepartmentID = 3
context.Entry(course).Reference(c => c.Department).Load();
Dalam asosiasi independen, akhir terkait objek dependen dikueri berdasarkan nilai kunci asing yang saat ini ada dalam database. Namun, jika hubungan dimodifikasi, dan properti referensi pada objek dependen menunjuk ke objek utama berbeda yang dimuat dalam konteks objek, Kerangka Kerja Entitas akan mencoba membuat hubungan seperti yang didefinisikan pada klien.
Mengelola konkurensi
Dalam asosiasi kunci asing dan independen, pemeriksaan konkurensi didasarkan pada kunci entitas dan properti entitas lain yang ditentukan dalam model. Saat menggunakan EF Designer untuk membuat model, atur ConcurrencyMode
atribut ke tetap untuk menentukan bahwa properti harus diperiksa konkurensinya. Saat menggunakan Kode Pertama untuk menentukan model, gunakan ConcurrencyCheck
anotasi pada properti yang ingin Anda periksa konkurensinya. Saat bekerja dengan Code First, Anda juga dapat menggunakan TimeStamp
anotasi untuk menentukan bahwa properti harus diperiksa konkurensinya. Anda hanya dapat memiliki satu properti tanda waktu di kelas tertentu. Kode Pertama memetakan properti ini ke bidang yang tidak dapat diubah ke null dalam database.
Kami menyarankan agar Anda selalu menggunakan asosiasi kunci asing saat bekerja dengan entitas yang berpartisipasi dalam pemeriksaan dan resolusi konkurensi.
Untuk informasi selengkapnya, lihat Menangani Konflik Konkurensi.
Bekerja dengan Kunci yang tumpang tindih
Kunci yang tumpang tindih adalah kunci komposit di mana beberapa properti dalam kunci juga merupakan bagian dari kunci lain dalam entitas. Anda tidak dapat memiliki kunci yang tumpang tindih dalam asosiasi independen. Untuk mengubah asosiasi kunci asing yang mencakup kunci yang tumpang tindih, kami sarankan Anda memodifikasi nilai kunci asing alih-alih menggunakan referensi objek.