Code-first vs Model / Database-first [ditutup]

618

Apa pro & kontra menggunakan Entity Framework 4.1 Code-first over Model / Database-first dengan diagram EDMX?

Saya mencoba untuk sepenuhnya memahami semua pendekatan untuk membangun lapisan akses data menggunakan EF 4.1. Saya menggunakan pola Repositori dan IoC.

Saya tahu saya bisa menggunakan pendekatan kode-pertama: mendefinisikan entitas dan konteks saya dengan tangan dan menggunakan ModelBuilderuntuk menyempurnakan skema.

Saya juga bisa membuat EDMXdiagram dan memilih langkah pembuatan kode yang menggunakan templat T4 untuk menghasilkan POCOkelas yang sama .

Dalam kedua kasus saya berakhir dengan POCOobjek yang ORMagnostik dan konteks yang berasal DbContext.

Database-pertama tampaknya paling menarik karena saya dapat merancang database di Enterprise Manager, dengan cepat menyinkronkan model dan menyempurnakannya menggunakan desainer.

Jadi apa perbedaan antara kedua pendekatan itu? Apakah hanya tentang preferensi VS2010 vs Enterprise Manager?

Jakub Konecki
sumber
12
Entity Framework 7 menjatuhkan EDMX: msdn.microsoft.com/en-us/magazine/dn890367.aspx
CAD bloke
5
@CADbloke Entity Framework 7 sekarang adalah Entity Framework Core 1.0
RBT
6
Untuk peramban lain, kecuali jika Anda memiliki hardon untuk 7000 file XML yang panjang dan menyelesaikan konflik penggabungan di atas, buka kode terlebih dahulu dan selamatkan diri Anda dari sakit kepala
Dan Pantry
3
Ada yang baik Jan 2015 write-up pada tiga pendekatan di roland.kierkels.net/c-asp-net/...
danio
4
Hampir setiap jawaban yang diberikan adalah "Saya Pikirkan" ... definisi absolut dari "Berdasarkan Opini Utama".
Lankymart

Jawaban:

703

Saya pikir perbedaannya adalah:

Kode dulu

  • Sangat populer karena programmer hardcore tidak menyukai segala jenis desainer dan mendefinisikan pemetaan dalam EDMX xml terlalu rumit.
  • Kontrol penuh atas kode (tidak ada kode otomatis yang sulit dimodifikasi).
  • Harapan umum adalah Anda tidak repot dengan DB. DB hanyalah penyimpanan tanpa logika. EF akan menangani pembuatan dan Anda tidak ingin tahu bagaimana cara kerjanya.
  • Perubahan manual ke basis data akan sangat mungkin hilang karena kode Anda menentukan basis data.

Database dulu

  • Sangat populer jika Anda memiliki DB yang dirancang oleh DBA, dikembangkan secara terpisah atau jika Anda memiliki DB yang ada.
  • Anda akan membiarkan EF membuat entitas untuk Anda dan setelah modifikasi pemetaan Anda akan menghasilkan entitas POCO.
  • Jika Anda menginginkan fitur tambahan dalam entitas POCO Anda harus memodifikasi template T4 atau menggunakan kelas parsial.
  • Perubahan manual ke database dimungkinkan karena database menentukan model domain Anda. Anda selalu dapat memperbarui model dari basis data (fitur ini berfungsi cukup baik).
  • Saya sering menggunakan ini bersama proyek VS Database (hanya versi Premium dan Ultimate).

Model dulu

  • IMHO populer jika Anda penggemar desainer (= Anda tidak suka menulis kode atau SQL).
  • Anda akan "menggambar" model Anda dan membiarkan alur kerja menghasilkan skrip database Anda dan templat T4 menghasilkan entitas POCO Anda. Anda akan kehilangan sebagian kendali pada entitas dan basis data Anda, tetapi untuk proyek-proyek kecil yang mudah, Anda akan sangat produktif.
  • Jika Anda menginginkan fitur tambahan dalam entitas POCO Anda harus memodifikasi template T4 atau menggunakan kelas parsial.
  • Perubahan manual ke basis data akan sangat mungkin hilang karena model Anda mendefinisikan basis data. Ini berfungsi lebih baik jika Anda memiliki paket pembangkit generasi Database yang diinstal. Ini akan memungkinkan Anda memperbarui skema basis data (alih-alih membuat ulang) atau memperbarui proyek basis data di VS.

Saya berharap bahwa dalam kasus EF 4.1 ada beberapa fitur lain yang terkait dengan Code First vs. Model / Database terlebih dahulu. API Lancar yang digunakan dalam Kode pertama tidak menawarkan semua fitur EDMX. Saya berharap bahwa fitur-fitur seperti pemetaan prosedur tersimpan, tampilan kueri, pandangan mendefinisikan dll berfungsi ketika menggunakan Model / Database terlebih dahulu dan DbContext(saya belum mencobanya) tetapi mereka tidak dalam Kode terlebih dahulu.

Ladislav Mrnka
sumber
5
@Ladislav - terima kasih atas jawaban komprehensifnya. Hanya untuk memperjelas: kecuali untuk beberapa batasan API yang lancar tidak ada perbedaan teknis nyata antara pendekatan-pendekatan itu? Ini lebih tentang pengembangan / proses penyebaran / metodologi? Sebagai contoh, saya memiliki lingkungan terpisah untuk Dev / Test / Beta / Prod dan saya akan meningkatkan basis data secara manual pada Beta / Prod karena perubahan pada skema mungkin memerlukan beberapa modifikasi data yang kompleks. Dengan Dev / Test, saya senang EF mengeluarkan dan membuat basis data karena saya sendiri akan mengunggahnya dengan data uji di inisialisasi.
Jakub Konecki
152
Saya telah mendesain database begitu lama sehingga saya tidak bisa membayangkan melakukan apa pun selain database terlebih dahulu. Bahkan, saya masih menulis banyak prosedur tersimpan untuk pernyataan pilih volume yang lebih tinggi dan semacamnya, dan kemudian saya akan melakukan fungsi impor ke dalam model EF semua atas nama kinerja.
Steve Wortham
9
Apa yang Anda maksud dengan pernyataan pilih volume tinggi? Prosedur tersimpan tidak lebih cepat daripada SELECT dikirim dari aplikasi.
Piotr Perak
20
Anda dapat memiliki SQL di aplikasi Anda. SQL itu kemungkinan besar akan tertanam dalam kode yang dikompilasi, dan setiap perubahan akan memerlukan kompilasi ulang dan penempatan ulang sementara perubahan Prosedur Tersimpan hanya akan memerlukan pengeditan Prosedur Tersimpan. Pelanggan / Klien / Pengguna akan kurang terpengaruh oleh perubahan dalam hal ini.
CodeWarrior
5
@JakubKonecki, apa pun yang Anda tidak temukan di DbContextyang ada ObjectContextcukup gunakan ((IObjectContextAdapter)dbcontext).ObjectContext.
Shimmy Weitzhandler
134

Saya pikir "pohon keputusan" sederhana ini oleh Julie Lerman penulis "Programming Entity Framework" harus membantu membuat keputusan dengan lebih percaya diri:

pohon keputusan untuk membantu memilih berbagai pendekatan dengan EF

Info lebih lanjut Di Sini .

Bahador Izadpanah
sumber
111
Ini tidak lengkap. Bagaimana jika Anda lebih suka TIDAK menggunakan desainer visual tetapi Anda memang memiliki database?
Dave New
14
Lebih buruk lagi ... keputusan kehidupan nyata tidak dilakukan oleh diagram, melainkan oleh keterbatasan teknis yang Anda hadapi saat menggunakan kode-pertama, misalnya Anda tidak dapat membuat indeks unik pada bidang atau Anda tidak dapat menghapus data hierarkis di tabel pohon untuk ini Anda memerlukan CTE menggunakan konteks. Tabel. SQL Permintaan ("pilih ..."). Model / Database terlebih dahulu tidak memiliki kekurangan ini.
Elisabeth
32
@dewewza itu jalan pertama bukan?
Chris S
3
@davenewza database yang ada => kelas yang ada? Kode Pertama: Database pertama :)
riadh gomri
4
@davenewza Gunakan kerangka kerja Badan Powertools untuk membuat kelas POCO Anda dari DB. Kode Pertama ke Basis Data yang Ada
Iman Mahmoudinasab
50

Database pertama dan model pertama tidak memiliki perbedaan nyata. Kode yang dihasilkan sama dan Anda dapat menggabungkan pendekatan ini. Misalnya, Anda dapat membuat database menggunakan desainer, daripada Anda dapat mengubah database menggunakan skrip sql dan memperbarui model Anda.

Ketika Anda menggunakan kode terlebih dahulu, Anda tidak dapat mengubah model tanpa database rekreasi dan kehilangan semua data. IMHO, batasan ini sangat ketat dan tidak memungkinkan untuk menggunakan kode terlebih dahulu dalam produksi. Untuk saat ini itu tidak benar-benar dapat digunakan.

Kelemahan minor kedua dari kode pertama adalah bahwa pembuat model memerlukan hak istimewa pada database master. Ini tidak mempengaruhi Anda jika Anda menggunakan database SQL Server Compact atau jika Anda mengontrol server database.

Kelebihan kode pertama adalah kode yang sangat bersih dan sederhana. Anda memiliki kontrol penuh atas kode ini dan dapat dengan mudah memodifikasi dan menggunakannya sebagai model tampilan Anda.

Saya dapat merekomendasikan untuk menggunakan pendekatan kode pertama ketika Anda membuat aplikasi mandiri sederhana tanpa versi dan menggunakan model \ database terlebih dahulu dalam proyek yang membutuhkan modifikasi dalam produksi.

Stepan Smagin
sumber
7
Jika Anda akan memperbarui lingkungan produksi secara manual dengan skrip SQL, Anda masih dapat melakukan hal yang sama dengan Code First. Anda cukup membuat skrip perubahan seperlunya. Beberapa alat dapat mengotomatisasi delta-delta ini, dan Anda dapat terus menggunakan Code First. Anda hanya perlu mengubah initializer Code First menjadi sesuatu seperti CreateDatabaseIfNotExists agar tidak menghapus database saat ini.
Esteban Brenes
Beberapa perbedaan mengimpor tampilan kemudian membuat ulang basis data tempat tampilan menjadi tabel. Membuatnya sulit untuk membuat DB baru dan membandingkannya dengan prod DB untuk melihat apakah dalam sinkronisasi.
Dave
Model First tidak mendukung fungsi SQL yang ditentukan pengguna (setidaknya di EF4, tidak tahu apakah ini telah berubah). Dengan Database Pertama, Anda bisa mengimpor UDF dan menggunakannya di kueri LINQ Anda.
Tsahi Asher
Tidak ada perbedaan? Coba impor tampilan dan tabel SimpleMembership lalu buat database dari model dan lihat apa yang Anda dapatkan. Bahkan tidak dekat! Ini harus pulang pergi tetapi kemudian MSFT pada dasarnya telah meninggalkan MF dan DF sebagai pengganti CF yang juga tidak lengkap dalam hal menggunakan tampilan dan procs yang disimpan.
Dave
Anda dapat menonaktifkan kode proses migrasi basis data pertama berdasarkan migrasi dan melakukannya secara manual dalam model dan basis data. Anda dapat melakukannya dengan menentukan disableDatabaseInitialization = "true" di web / app.config Anda di <EntityFramework> ..... <contexts> <tipe konteks = "myNamespace.mydbContext", "myassemblyORProject" disableDatabaseInitialization = "true" /> </EntityFramework> Anda dapat menghapus folder migrasi.
Hasteq
37

Mengutip bagian-bagian yang relevan dari http://www.itworld.com/development/405005/3-reason-use-code-first-design-entity-framework

3 alasan untuk menggunakan desain kode pertama dengan Kerangka Entity

1) Kurang kasar, kurang kembung

Menggunakan database yang ada untuk menghasilkan file model .edmx dan model kode yang terkait menghasilkan tumpukan besar kode yang dibuat secara otomatis. Anda diminta untuk tidak menyentuh file-file yang dihasilkan ini agar Anda tidak merusak sesuatu, atau perubahan Anda akan ditimpa pada generasi berikutnya. Konteks dan penginisialisasi macet bersama dalam kekacauan ini juga. Saat Anda perlu menambahkan fungsionalitas ke model yang dibuat, seperti properti hanya-baca yang dihitung, Anda perlu memperluas kelas model. Ini akhirnya menjadi persyaratan untuk hampir setiap model dan Anda berakhir dengan ekstensi untuk semuanya.

Dengan kode terlebih dahulu model kode tangan Anda menjadi basis data Anda. File persis yang Anda buat adalah yang menghasilkan desain database. Tidak ada file tambahan dan tidak perlu membuat ekstensi kelas ketika Anda ingin menambahkan properti atau apa pun yang tidak perlu diketahui oleh database. Anda bisa menambahkannya ke kelas yang sama selama Anda mengikuti sintaks yang tepat. Heck, Anda bahkan dapat membuat file Model.edmx untuk memvisualisasikan kode Anda jika Anda mau.

2) Kontrol Yang Lebih Besar

Ketika Anda menggunakan DB terlebih dahulu, Anda berada di bawah kekuasaan apa yang dihasilkan untuk model Anda untuk digunakan dalam aplikasi Anda. Kadang-kadang konvensi penamaan tidak diinginkan. Terkadang hubungan dan asosiasi tidak seperti yang Anda inginkan. Di waktu lain, hubungan tidak transien dengan pemuatan malas mendatangkan malapetaka pada respons API Anda.

Meskipun hampir selalu ada solusi untuk masalah pembuatan model yang mungkin Anda temui, kode yang pertama kali memberi Anda kendali penuh dan halus dari awal. Anda dapat mengontrol setiap aspek dari kedua model kode Anda dan desain basis data Anda dari kenyamanan objek bisnis Anda. Anda dapat secara tepat menentukan hubungan, batasan, dan asosiasi. Anda dapat secara bersamaan menetapkan batas karakter properti dan ukuran kolom basis data. Anda dapat menentukan koleksi terkait mana yang ingin dimuat, atau tidak serialisasi sama sekali. Singkatnya, Anda bertanggung jawab untuk lebih banyak barang tetapi Anda memegang kendali penuh atas desain aplikasi Anda.

3) Kontrol Versi Basis Data

Ini yang besar. Database versi sulit, tetapi dengan kode pertama dan migrasi kode pertama, itu jauh lebih efektif. Karena skema basis data Anda sepenuhnya didasarkan pada model kode Anda, dengan versi mengendalikan kode sumber Anda, Anda membantu membuat versi database Anda. Anda bertanggung jawab untuk mengendalikan inisialisasi konteks Anda yang dapat membantu Anda melakukan hal-hal seperti seed data bisnis tetap. Anda juga bertanggung jawab untuk membuat migrasi kode pertama.

Saat Anda pertama kali mengaktifkan migrasi, kelas konfigurasi dan migrasi awal dihasilkan. Migrasi awal adalah skema Anda saat ini atau baseline v1.0 Anda. Mulai saat itu Anda akan menambahkan migrasi yang diberi cap waktu dan label dengan deskriptor untuk membantu memesan versi. Saat Anda memanggil migrasi tambahan dari manajer paket, file migrasi baru akan dibuat berisi semua yang telah berubah dalam model kode Anda secara otomatis baik dalam fungsi ATAS () maupun BAWAH (). Fungsi UP menerapkan perubahan pada database, fungsi DOWN menghapus perubahan yang sama jika Anda ingin mengembalikan. Terlebih lagi, Anda dapat mengedit file migrasi ini untuk menambahkan perubahan tambahan seperti tampilan baru, indeks, prosedur tersimpan, dan apa pun lainnya. Mereka akan menjadi sistem versi yang benar untuk skema basis data Anda.

Kata Roohullah Allem
sumber
31

Code-first tampaknya adalah bintang yang naik daun. Saya melihat Ruby on Rails dengan cepat, dan standar mereka adalah kode-pertama, dengan migrasi basis data.

Jika Anda sedang membangun aplikasi MVC3, saya percaya Code pertama memiliki keuntungan sebagai berikut:

  • Dekorasi atribut yang mudah - Anda dapat menghiasi bidang dengan validasi, memerlukan, dll. Atribut, cukup canggung dengan pemodelan EF
  • Tidak ada kesalahan pemodelan yang aneh - Pemodelan EF sering memiliki kesalahan aneh, seperti ketika Anda mencoba mengubah nama properti asosiasi, itu harus cocok dengan meta-data yang mendasarinya - sangat tidak fleksibel.
  • Tidak aneh untuk bergabung - Saat menggunakan alat kontrol versi kode seperti mercurial, menggabungkan file .edmx adalah hal yang menyebalkan. Anda seorang programmer yang terbiasa dengan C #, dan di sana Anda menggabungkan .edmx. Tidak demikian halnya dengan kode-pertama.
  • Kontras kembali ke Kode terlebih dahulu dan Anda memiliki kontrol penuh tanpa semua kompleksitas tersembunyi dan tidak diketahui untuk ditangani.
  • Saya sarankan Anda menggunakan alat baris perintah Package Manager, bahkan tidak menggunakan alat grafis untuk menambahkan controller baru ke tampilan scaffold.
  • DB-Migrations - Kemudian Anda juga dapat Mengaktifkan-Migrasi. Ini sangat kuat. Anda membuat perubahan pada model Anda dalam kode, dan kemudian kerangka kerja dapat melacak perubahan skema, sehingga Anda dapat menerapkan peningkatan secara mulus, dengan versi skema yang ditingkatkan secara otomatis (dan diturunkan jika diperlukan). (Tidak yakin, tapi ini mungkin berhasil dengan model-pertama juga)

Memperbarui

Pertanyaannya juga meminta perbandingan kode-pertama dengan model EDMX / db-pertama. Code-first dapat digunakan untuk kedua pendekatan ini juga:

Todd
sumber
3
Model-first tidak mengkode POCO terlebih dahulu, ini adalah Code First, Model-First adalah Desainer Visual untuk secara otomatis menghasilkan POCO dan setelah itu menghasilkan basis data dari model.
Diego Mendes
Saat ini baik dalam rute visual dan kode, Anda dapat melakukan "Model" terlebih dahulu atau "Database" terlebih dahulu. Yang pertama adalah desain manual (baik melalui kode atau editor visual), yang kedua adalah membangun database dan membuat model (baik POCOs atau EDMX).
Todd
11

Saya menggunakan basis data EF terlebih dahulu untuk memberikan lebih banyak fleksibilitas dan kontrol atas konfigurasi basis data.

Pertama kode EF dan model pertama tampak keren pada awalnya, dan memberikan kemandirian basis data, namun dalam melakukan hal ini tidak memungkinkan Anda untuk menentukan apa yang saya anggap informasi konfigurasi basis data yang sangat mendasar dan umum. Misalnya indeks tabel, metadata keamanan, atau memiliki kunci utama yang berisi lebih dari satu kolom. Saya menemukan saya ingin menggunakan ini dan fitur-fitur database umum lainnya dan karena itu harus melakukan beberapa konfigurasi database secara langsung.

Saya menemukan kelas POCO default yang dihasilkan selama DB pertama sangat bersih, namun tidak memiliki atribut anotasi data yang sangat berguna, atau pemetaan untuk prosedur yang tersimpan. Saya menggunakan template T4 untuk mengatasi beberapa keterbatasan ini. Templat T4 mengagumkan, terutama jika dikombinasikan dengan metadata dan kelas parsial Anda sendiri.

Model pertama tampaknya memiliki banyak potensi, tetapi memberi saya banyak bug selama refactoring skema database yang kompleks. Tidak yakin kenapa.

pengguna1618371
sumber
4
Anda dapat menentukan kunci komposit menggunakan kode terlebih dahulu - stackoverflow.com/questions/5466374/...
Jakub Konecki
3
Untuk pembaca yang akan datang, ini bukan lagi masalahnya, Anda dapat menambahkan Indeks, kunci utama multi-kolom, dan hal-hal semacam ini di EF Code First.
tobiak777
1
EF seharusnya diperbaiki sehingga ketiga pendekatan dapat digunakan secara bergantian pada database yang sama karena ada kelebihan dan kekurangan untuk ketiga pendekatan
Dave
Selain itu kebenaran dari solusi kode yang tidak ideal pertama saya menggunakan database terlebih dahulu karena migrasi ke IDE / Bahasa lain di masa depan dan saya ingin memiliki struktur basis data yang solid dan terintegrasi, fakta lain yang saya lebih suka database pertama adalah fleksibilitas dalam mengubah setiap bagian dari penyimpanan data.
QMaster
7

Bekerja dengan model besar sangat lambat sebelum SP1, (belum mencobanya setelah SP1, tetapi dikatakan sekarang sangat mudah).

Saya masih mendesain meja saya terlebih dahulu, kemudian alat in-house yang dibuat menghasilkan POCO untuk saya, sehingga dibutuhkan beban melakukan tugas yang berulang untuk setiap objek poco.

ketika Anda menggunakan sistem kontrol sumber, Anda dapat dengan mudah mengikuti sejarah POCO Anda, tidak mudah dengan kode yang dihasilkan desainer.

Saya memiliki basis untuk POCO saya, yang membuat banyak hal cukup mudah.

Saya memiliki pandangan untuk semua tabel saya, setiap tampilan dasar membawa info dasar untuk kunci asing saya dan pandangan saya POCO berasal dari kelas POCO saya, yang sangat berguna lagi.

Dan akhirnya saya tidak suka desainer.

hazimdikenli
sumber
8
'ketika Anda menggunakan sistem kontrol sumber, Anda dapat dengan mudah mengikuti sejarah POCO Anda, itu tidak mudah dengan kode yang dihasilkan desainer.' - Saya menyimpan kode yang dibuat perancang di Kontrol Sumber, jadi saya selalu dapat melihat riwayat.
Jakub Konecki
1
@JakubKonecki Apakah Anda pernah mencoba menggabungkan file EDMX dalam tim yang terdiri dari 3 orang? Itu hanya menyusahkan ... Sebaliknya orang mencoba untuk menghindari penggabungan dan hanya mengambil revisi yang lain dan mengulangi perubahan mereka sendiri, karena penggabungan cenderung gagal dalam file yang dibuat secara otomatis dengan ribuan baris XML.
bytecode77
6

Contoh pertama pendekatan basis data:

Tanpa menulis kode apa pun: ASP.NET MVC / MVC3 Database First Approach / Database terlebih dahulu

Dan saya pikir itu lebih baik daripada pendekatan lain karena kehilangan data kurang dengan pendekatan ini.

AUKI
sumber
Bisakah Anda menguraikan 'kehilangan data yang lebih sedikit' dengan pendekatan pertama DB? Bagaimana Anda melakukan transformasi data jika Anda membagi tabel yang ada menjadi dua?
Jakub Konecki
Anda mungkin akan akhirnya menulis skrip sql yang memperhatikan transformasi. Secara umum, MS mengumumkan untuk meningkatkan migrasi data Code First dengan versi baru mereka, jadi ini mungkin bukan argumen di masa depan.
ckonig
Masalah dengan basis data pertama adalah desain basis data umumnya memiliki abstraksi yang salah yang bocor ke dalam model Anda ... tabel persimpangan, dll. Tugas basis data hanya untuk mempertahankan model Anda.
Nerdfest
"Jawaban" ini adalah pendapat yang tidak berdasar pada argumen Anda, satu kalimat tidak membuat pendirian.
TravisO
Bisakah Anda menguraikan 'kehilangan data yang lebih sedikit' dengan pendekatan pertama DB?
amal50
4

IMHO Saya berpikir bahwa semua model memiliki tempat yang bagus tetapi masalah yang saya miliki dengan pendekatan pertama model adalah di banyak bisnis besar dengan DBA mengendalikan database Anda tidak mendapatkan fleksibilitas membangun aplikasi tanpa menggunakan pendekatan basis data terlebih dahulu. Saya telah bekerja di banyak proyek dan ketika datang untuk penempatan mereka ingin kontrol penuh.

Jadi sebanyak yang saya setuju dengan semua variasi yang mungkin Kode Pertama, Model Pertama, Database pertama, Anda harus mempertimbangkan lingkungan produksi yang sebenarnya. Jadi jika sistem Anda akan menjadi aplikasi basis pengguna yang besar dengan banyak pengguna dan DBA yang menjalankannya, maka Anda dapat mempertimbangkan opsi Basis Data pertama hanya pendapat saya.

Matthew Parton
sumber
Kamu benar. MS memberikan programmer pendekatan yang berbeda karena skenario yang berbeda. Anda harus mengetahui semua dan memutuskan berdasarkan skenario Anda apa yang terbaik untuk proyek tersebut, dan kemudian apa yang paling Anda sukai.
Sterling Diaz
0

Saya pikir salah satu Kelebihan kode pertama adalah bahwa Anda dapat membuat cadangan semua perubahan yang Anda buat ke sistem kontrol versi seperti Git. Karena semua tabel dan hubungan Anda disimpan dalam apa yang pada dasarnya hanya kelas, Anda dapat kembali ke masa lalu dan melihat struktur database Anda sebelumnya.

anonymous_dojo
sumber