Kedua entitas tersebut adalah hubungan satu-ke-banyak (dibangun dengan kode pertama fasih api).
public class Parent
{
public Parent()
{
this.Children = new List<Child>();
}
public int Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Data { get; set; }
}
Di pengontrol WebApi saya, saya memiliki tindakan untuk membuat entitas induk (yang berfungsi dengan baik) dan memperbarui entitas induk (yang memiliki beberapa masalah). Tindakan pembaruan terlihat seperti:
public void Update(UpdateParentModel model)
{
//what should be done here?
}
Saat ini saya punya dua ide:
Dapatkan entitas induk terlacak yang dinamai
existing
olehmodel.Id
, dan tetapkan nilaimodel
satu per satu ke entitas tersebut. Ini kedengarannya bodoh. Danmodel.Children
saya tidak tahu anak mana yang baru, anak mana yang dimodifikasi (atau bahkan dihapus).Buat entitas induk baru melalui
model
, dan lampirkan ke DbContext dan simpan. Tetapi bagaimana DbContext bisa mengetahui keadaan anak-anak (baru tambah / hapus / modifikasi)?
Apa cara yang benar dalam mengimplementasikan fitur ini?
sumber
Jawaban:
Karena model yang akan diposting ke pengontrol WebApi terlepas dari konteks entitas-kerangka kerja (EF), satu-satunya pilihan adalah memuat grafik objek (induk termasuk anak-anaknya) dari database dan membandingkan mana yang telah ditambahkan, dihapus atau diperbarui. (Kecuali jika Anda akan melacak perubahan dengan mekanisme pelacakan Anda sendiri selama keadaan terpisah (di browser atau di mana pun) yang menurut saya lebih kompleks daripada yang berikut ini.) Ini bisa terlihat seperti ini:
...CurrentValues.SetValues
dapat mengambil objek apa pun dan memetakan nilai properti ke entitas terlampir berdasarkan nama properti. Jika nama properti dalam model Anda berbeda dari nama-nama di entitas Anda tidak dapat menggunakan metode ini dan harus menetapkan nilai satu per satu.sumber
existingParent.Children.Add(newChild)
karena pencarian linq anak yang ada akan mengembalikan entitas yang baru ditambahkan, sehingga entitas tersebut akan diperbarui. Anda hanya perlu memasukkan ke dalam daftar sementara dan kemudian menambahkan.existingChild
permintaan LINQ:.Where(c => c.ID == childModel.ID && c.ID != default(int))
Saya telah mengacaukan dengan sesuatu seperti ini ...
yang dapat Anda hubungi dengan sesuatu seperti:
Sayangnya, ini agak jatuh jika ada properti koleksi pada tipe anak yang juga perlu diperbarui. Mempertimbangkan mencoba menyelesaikan ini dengan mengirimkan IRepository (dengan metode CRUD dasar) yang akan bertanggung jawab untuk memanggil UpdateChildCollection sendiri. Akan memanggil repo bukannya panggilan langsung ke DbContext.Entry.
Tidak tahu bagaimana ini semua akan tampil pada skala, tetapi tidak yakin apa lagi yang harus dilakukan dengan masalah ini.
sumber
toAdd.ForEach(i => (selector(dbItem) as ICollection<Tchild>).Add(i.Value));
harus menyelesaikan masalah n -> n.Baiklah kawan Saya punya jawaban ini sekali tetapi hilang di sepanjang jalan. penyiksaan mutlak ketika Anda tahu ada cara yang lebih baik tetapi tidak dapat mengingatnya atau menemukannya! Ini sangat sederhana. Saya baru saja mengujinya dengan berbagai cara.
Anda dapat mengganti seluruh daftar dengan yang baru! Kode SQL akan menghapus dan menambahkan entitas sesuai kebutuhan. Tidak perlu khawatir dengan itu. Pastikan untuk memasukkan koleksi anak atau tidak ada dadu. Semoga berhasil!
sumber
Jika Anda menggunakan EntityFrameworkCore, Anda dapat melakukan hal berikut ini di tindakan post controller Anda ( Metode Attach secara melampirkan properti navigasi termasuk koleksi):
Diasumsikan bahwa setiap entitas yang diperbarui memiliki semua properti yang ditetapkan dan disediakan dalam data pos dari klien (mis. Tidak akan berfungsi untuk pembaruan parsial suatu entitas).
Anda juga perlu memastikan bahwa Anda menggunakan konteks basis data kerangka kerja entitas baru / khusus untuk operasi ini.
sumber
Inilah cara saya memecahkan masalah ini. Dengan cara ini, EF tahu mana yang akan ditambahkan untuk diperbarui.
sumber
Ada beberapa proyek di luar sana yang membuat interaksi antara klien dan server lebih mudah sejauh menyangkut menyimpan seluruh grafik objek.
Berikut adalah dua yang ingin Anda lihat:
Kedua proyek di atas mengenali entitas yang terputus saat dikembalikan ke server, mendeteksi dan menyimpan perubahan, dan kembali ke data klien yang terpengaruh.
sumber
Hanya bukti konsep
Controler.UpdateModel
tidak akan berfungsi dengan benar.Kelas penuh di sini :
sumber
@Charles McIntosh benar-benar memberi saya jawaban untuk situasi saya karena model yang dilewati terlepas. Bagi saya apa yang akhirnya berhasil adalah menyelamatkan model yang lulus terlebih dahulu ... kemudian terus menambahkan anak-anak seperti yang sudah saya lakukan sebelumnya:
sumber
Untuk pengembang VB.NET Gunakan sub generik ini untuk menandai status anak, mudah digunakan
sumber
sumber
sumber
Ini kode saya yang berfungsi dengan baik.
sumber