Apakah antarmuka yang lancar lebih fleksibel daripada atribut dan mengapa?

15

Dalam tutorial EF 4.1 Code First, kode berikut diberikan:

public class Department
{
    public int DepartmentId { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Collaborator> Collaborators { get; set; }
}

Kemudian dijelaskan bahwa antarmuka yang lancar lebih fleksibel:

Anotasi data jelas mudah digunakan tetapi lebih baik menggunakan pendekatan terprogram yang memberikan lebih banyak fleksibilitas.

Contoh menggunakan antarmuka fasih kemudian diberikan:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Department>().Property(dp => dp.Name).IsRequired();
    modelBuilder.Entity<Manager>().HasKey(ma => ma.ManagerCode);
    modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .IsConcurrencyToken(true)
        .IsVariableLength()
        .HasMaxLength(20);
}

Saya tidak mengerti mengapa antarmuka yang lancar seharusnya lebih baik. Benarkah itu? Dari sudut pandang saya, sepertinya penjelasan data lebih jelas, dan lebih terasa semantik.

Pertanyaan saya adalah mengapa antarmuka yang lancar menjadi pilihan yang lebih baik daripada menggunakan atribut, terutama dalam hal ini?

(Catatan: Saya cukup baru dalam keseluruhan konsep antarmuka yang lancar, jadi harap tidak ada pengetahuan sebelumnya tentang ini.)

Referensi: http://codefirst.codeplex.com/

Tjaart
sumber
Pertanyaan ini sebenarnya bukan tentang antarmuka yang lancar. Perbedaannya adalah antara menggunakan atribut dan kode normal. Jika kodenya tidak lancar, itu tidak akan banyak berubah tentang pertanyaan Anda.
svick
@svick antarmuka yang lancar pada dasarnya adalah kode normal, tetapi mengekspresikannya dengan cara yang berbeda Kami beralih dari menetapkan hal-hal dalam kode biasa ke atribut, sekarang dengan antarmuka yang lancar sepertinya beberapa mundur dan bergerak ke arah menentukan hal-hal dalam kode lagi. Saya hanya ingin mengerti mengapa Anda menggunakan kode alih-alih atribut. Apakah antarmuka yang lancar menjamin pindah dari atribut dan kembali ke pengkodean semuanya lagi?
Tjaart

Jawaban:

13

Anotasi data bersifat statis, misalnya pernyataan metode ini tidak dapat berubah saat runtime:

  [MinLength(5)]
  [MaxLength(20,ErrorMessage="Le nom ne peut pas avoir plus de 20 caractères")]
  public new string Name { get; set; }

Antarmuka yang lancar bisa dinamis:

   if (longNamesEnabled)
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(100);
   }
   else
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(20);
   }

Belum lagi kode tersebut dapat digunakan kembali di antara properti.

Garrett Hall
sumber
2
mengapa Anda berpikir bahwa panjang (atau properti lainnya) dari properti yang sama akan berubah dalam waktu berjalan?
Yusubov
1
@ ElYusubov: Saya akan mulai dengan skenario di mana saya tidak tahu panjang bidang pada waktu pengkodean.
Wyatt Barnett
@ WyattBarnett: masuk akal untuk memiliki panjang bidang sebagai variabel hanya ketika parameter domain diambil secara dinamis dari beberapa layanan atau sumber un-mengetik eksternal. Namun, berurusan secara dinamis dengan properti domain akan membutuhkan pendekatan pengkodean defensif.
Yusubov
1
@ ElYusubov Anda bisa memiliki dua properti yang harus persis sama kecuali untuk panjang jadi saya meneruskannya ke fungsi yang mengaturnya secara dinamis. Inilah sebabnya mengapa penulis menyebut mereka lebih fleksibel.
Garrett Hall
1
@ ElYusubov, Anda bisa membuat panjang bidang pengaturan di pengaturan proyek, yang dimasukkan ke app.config atau web.config. Kemudian jika panjang bidang basis data berubah, Anda bisa mengubah panjang dalam file .config tanpa mengkompilasi ulang dan memindahkan aplikasi.
Kyralessa
8

Saya tidak berpikir bahwa pernyataan itu harus diterapkan secara luas; ini sangat spesifik untuk Code First. Dalam Kode Pertama, anotasi data hanya menyertakan sebagian fungsi yang tersedia di API yang lancar. Dengan kata lain, ada konfigurasi model tertentu yang hanya dapat dilakukan menggunakan API yang lancar.

Sebagai contoh, berikut adalah beberapa hal yang tidak dapat ditentukan menggunakan anotasi:

  • Ketepatan properti DateTime
  • Ketepatan dan skala sifat numerik
  • Properti String atau Binary sebagai panjang tetap
  • Properti String sebagai non-unicode
  • Perilaku hubungan yang dihapus saat ini
  • Strategi pemetaan lanjutan

Secara pribadi, saya cenderung menggunakan anotasi data yang berhubungan dengan validasi jika memungkinkan karena teknologi lain seperti MVC juga dapat memanfaatkan ini. Untuk yang lainnya, saya lebih suka API yang lancar.

bricelam
sumber
Bisakah Anda memberikan contoh tentang apa yang hanya dapat dilakukan dengan menggunakan API yang lancar? Menarik juga untuk mengetahui mengapa mereka memilih untuk melakukannya dengan cara ini. Saya mencoba memahami API murni versus metode dan kerangka kerja entitas yang lebih konvensional hanyalah sebuah contoh. Saya ingin tahu mengapa mereka lebih suka atribut. Bagi saya atribut tampak lebih benar dan mudah dibaca.
Tjaart
1
@ Metroart saya telah menambahkan beberapa contoh. Saat merancang ini, ada dua prinsip motivasi utama. Pertama, izinkan dev untuk memilih. Beberapa orang melihat atribut sebagai pelanggaran POCO, yang lain menyukai sifat deklaratif mereka. Kedua, memanfaatkan atribut yang ada dan hanya memperkenalkan yang baru untuk skenario umum. Anda mungkin akan setuju bahwa contoh yang saya berikan di atas relatif tidak umum.
bricelam
Saya memang memperhatikan bahwa perilaku OnDelete tampaknya hanya tersedia di API yang lancar. Dapatkah Anda memikirkan mengapa mereka memilih untuk melakukannya dengan cara ini? Ini benar-benar apa yang saya coba untuk menjawab pertanyaan ini. Pelanggaran POCO mungkin menjadi alasan yang bagus jika Anda berbagi kelas antar proyek. Anda mungkin akhirnya menarik ketergantungan kerangka kerja entitas yang tidak Anda inginkan jika Anda menggunakan atribut!
Tjaart
@ Tomart, saya tidak ingat alasan pastinya. Saya bergabung dengan tim menjelang akhir fitur Code First dan tidak di sini untuk desain itu. Saya akan melihat apakah saya bisa membuat orang lain dari tim untuk menimbang.
bricelam
1

Jawaban untuk pertanyaan Anda disediakan di tautan.

Kemudian Anda menentukan batasan Anda yang berlaku untuk domain Anda dalam metode ini secara terprogram.

Pada dasarnya, ini lebih atau kurang preferensi untuk menggunakan pendekatan Atribut vs programatik, di mana pendekatan programatik memiliki kontrol lebih besar atas entitas. Namun, ada cara kustom untuk menambahkan Atribut untuk menghias model Anda sehingga Anda mungkin terlihat juga.

Saat menggunakan pendekatan ini Anda bahkan dapat menggambarkan hubungan antara tabel dan kolom. Intinya, jika Anda bersedia memiliki kendali lebih besar atas domain Anda, Anda dapat menggunakan pendekatan baru ini yang datang dengan EF4.1.

Namun, untuk skenario umum validasi menerapkan Atribut harus berfungsi dengan baik karena kuat untuk mencakup sebagian besar kasus; dan selain itu mungkin menghemat waktu Anda.

Yusubov
sumber
Bisakah Anda menggambarkan bagaimana cara programatik memberi Anda lebih banyak kendali? Saya tidak benar-benar mengerti pada saat ini.
Tjaart
Misalnya, ambil ini ".IsConcurrencyToken (true)" - bagaimana Anda akan melakukan ini pada definisi atribut?
Yusubov
[ConcurrencyCheck] <- yang sebenarnya tampak lebih sederhana
Tjaart
tangkapan yang bagus, bagaimana Anda menggambarkan "hubungan antara tabel dan kolom"?
Yusubov
[ForeignKey ("PersonId")] <- seperti itu, yang mungkin tidak semudah .HasForeignKey (t => t.ProjectId), meskipun semua yang diperlukan adalah membiarkan ForeignKey () mengambil lambda seperti antarmuka yang lancar. Itu masih tidak menjelaskan mengapa yang satu lebih baik dari yang lain.
Tjaart
0

Pikir saya adalah mereka merekomendasikan API yang lancar untuk implementasi kode pertama karena Anda secara eksplisit menggambarkan bagaimana hubungan dibuat dalam database. Jika Anda menggunakan anotasi data, basis data yang dibuat oleh Entity Framework mungkin tidak seperti yang Anda harapkan. Contoh awal Anda sangat sederhana, jadi seperti Anda, saya hanya akan menggunakan metode anotasi data.

str8killinit
sumber
Bisakah Anda memberikan contoh databse yang tidak sesuai dengan yang Anda harapkan dan bagaimana antarmuka yang lancar mencegah hal ini terjadi?
Tjaart