ส่วนต่อประสานที่คล่องแคล่วมีความยืดหยุ่นมากกว่าคุณสมบัติและทำไม?


15

ในการสอนโค้ด EF 4.1 รหัสแรกจะได้รับรหัสต่อไปนี้:

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

จากนั้นจะอธิบายว่าอินเทอร์เฟซที่คล่องแคล่วมีความยืดหยุ่นมากขึ้น:

คำอธิบายประกอบข้อมูลนั้นใช้งานง่ายอย่างแน่นอน แต่ควรใช้วิธีการเขียนโปรแกรมที่ให้ความยืดหยุ่นมากกว่า

ตัวอย่างของการใช้ส่วนต่อประสานที่คล่องแคล่วจะได้รับ:

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);
}

ฉันไม่เข้าใจว่าทำไมอินเทอร์เฟซที่คล่องแคล่วดีกว่าที่คาดคะเน มันจริงเหรอ? จากมุมมองของฉันดูเหมือนว่าคำอธิบายประกอบข้อมูลจะชัดเจนยิ่งขึ้นและมีความรู้สึกที่ชัดเจนมากขึ้น

คำถามของฉันคือทำไมส่วนต่อประสานที่คล่องแคล่วจะเป็นตัวเลือกที่ดีกว่าการใช้แอตทริบิวต์โดยเฉพาะในกรณีนี้

(หมายเหตุ: ฉันค่อนข้างใหม่กับแนวคิดทั้งหมดของส่วนต่อประสานที่คล่องแคล่วดังนั้นโปรดคาดหวังว่าจะไม่มีความรู้ก่อนหน้านี้)

การอ้างอิง: http://codefirst.codeplex.com/


คำถามนี้ไม่ได้เกี่ยวกับอินเตอร์เฟสที่คล่องแคล่วจริงๆ ความแตกต่างระหว่างการใช้คุณลักษณะและรหัสปกติ หากรหัสไม่คล่องมันจะไม่เปลี่ยนแปลงคำถามของคุณมากนัก
svick

@svick ส่วนต่อประสานที่คล่องแคล่วนั้นเป็นรหัสปกติ แต่มันแสดงออกในรูปแบบที่ต่างออกไป เราย้ายออกไปจากการระบุสิ่งต่าง ๆ ในรหัสธรรมดาไปยังแอตทริบิวต์ตอนนี้ด้วยอินเทอร์เฟซที่คล่องแคล่วดูเหมือนว่าบางคนจะย้อนรอยและย้ายไปสู่การระบุสิ่งต่าง ๆ ในรหัสอีกครั้ง ฉันแค่อยากจะเข้าใจว่าทำไมคุณถึงต้องใช้รหัสแทนคุณสมบัติ อินเทอร์เฟซที่คล่องแคล่วรับประกันว่าจะย้ายออกจากแอตทริบิวต์และกลับไปที่การเข้ารหัสทุกอย่างอีกครั้งหรือไม่
Tjaart

คำตอบ:


13

คำอธิบายประกอบข้อมูลเป็นแบบคงที่ตัวอย่างเช่นการประกาศวิธีนี้ไม่สามารถเปลี่ยนแปลงได้ในขณะใช้งานจริง:

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

อินเทอร์เฟซที่คล่องแคล่วสามารถเป็นแบบไดนามิก:

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

ไม่ต้องพูดถึงรหัสที่สามารถนำมาใช้ใหม่ระหว่างคุณสมบัติ


2
ทำไมคุณถึงคิดว่าความยาว (หรือคุณสมบัติอื่นใด) ของคุณสมบัติเดียวกันนั้นจะเปลี่ยนแปลงในเวลาทำงาน
Yusubov

1
@ElYusubov: ฉันเริ่มต้นด้วยสถานการณ์ที่ฉันไม่ทราบความยาวของเขตข้อมูลในเวลาการเข้ารหัส
ไวแอตต์บาร์เน็ตต์

@WyattBarnett: มันอาจสมเหตุสมผลที่จะมีความยาวฟิลด์เป็นตัวแปรเฉพาะเมื่อพารามิเตอร์โดเมนถูกดึงแบบไดนามิกจากบริการบางอย่างหรือแหล่งภายนอกที่ไม่ได้พิมพ์ อย่างไรก็ตามการจัดการกับคุณสมบัติโดเมนแบบไดนามิกจะต้องใช้วิธีการเข้ารหัสป้องกัน
Yusubov

1
@ElYusubov คุณอาจมีคุณสมบัติสองอย่างที่ต้องเหมือนกันทุกประการยกเว้นความยาวดังนั้นฉันจึงส่งผ่านไปยังฟังก์ชันที่ตั้งค่าแบบไดนามิก นี่คือเหตุผลที่ผู้เขียนเรียกพวกเขาว่ายืดหยุ่นมากขึ้น
Garrett Hall

1
@ElYusubov คุณสามารถตั้งค่าความยาวของฟิลด์ในการตั้งค่าโครงการซึ่งฟีดลงใน app.config หรือ web.config จากนั้นหากความยาวของฟิลด์ฐานข้อมูลเปลี่ยนไปคุณสามารถเปลี่ยนความยาวในไฟล์. config ได้โดยไม่ต้องคอมไพล์และปรับใช้แอปซ้ำอีกครั้ง
Kyralessa

8

ฉันไม่คิดว่าควรใช้ข้อความอย่างกว้างขวาง มันเฉพาะเจาะจงกับ Code First มาก ใน Code First การเพิ่มความคิดเห็นของข้อมูลจะรวมเฉพาะส่วนย่อยของฟังก์ชันที่มีอยู่ใน API ที่คล่องแคล่ว กล่าวอีกนัยหนึ่งมีการกำหนดค่าแบบจำลองบางอย่างที่สามารถทำได้โดยใช้ API ได้อย่างคล่องแคล่วเท่านั้น

ตัวอย่างเช่นนี่คือบางสิ่งที่ไม่สามารถระบุได้โดยใช้คำอธิบายประกอบ:

  • ความแม่นยำของคุณสมบัติ DateTime
  • ความแม่นยำและขนาดของคุณสมบัติตัวเลข
  • คุณสมบัติสตริงหรือไบนารีเป็นความยาวคงที่
  • คุณสมบัติ String เป็น non-unicode
  • พฤติกรรมการลบความสัมพันธ์
  • กลยุทธ์การทำแผนที่ขั้นสูง

โดยส่วนตัวแล้วฉันมักจะใช้คำอธิบายประกอบที่เกี่ยวข้องกับการตรวจสอบข้อมูลทุกครั้งที่ทำได้เนื่องจากเทคโนโลยีอื่น ๆ เช่น MVC สามารถใช้ประโยชน์จากสิ่งเหล่านี้ได้ สำหรับทุกอย่างอื่นฉันชอบ API ที่คล่องแคล่ว


คุณสามารถยกตัวอย่างสิ่งที่สามารถทำได้โดยใช้ API ได้อย่างคล่องแคล่วเท่านั้น? มันน่าสนใจที่จะรู้ว่าทำไมพวกเขาถึงเลือกทำแบบนี้ ฉันกำลังพยายามทำความเข้าใจกับ API ของ fleunt กับวิธีการทั่วไปและเฟรมเวิร์กเอนทิตีเป็นเพียงตัวอย่าง ฉันต้องการรู้ว่าทำไมพวกเขาถึงชอบมันมากกว่าคุณสมบัติ คุณลักษณะสำหรับฉันดูเหมือนจะถูกต้องและสามารถอ่านได้มากขึ้น
Tjaart

1
@Tjaart ฉันได้เพิ่มตัวอย่าง ในขณะที่ออกแบบสิ่งนี้มีหลักการจูงใจอยู่สองประการ ขั้นแรกให้ devs เลือก บางคนมองว่าคุณลักษณะเป็นการละเมิด POCO บางคนชอบลักษณะที่เปิดเผย ประการที่สองใช้ประโยชน์จากคุณลักษณะที่มีอยู่และแนะนำใหม่สำหรับสถานการณ์ทั่วไปเท่านั้น คุณอาจเห็นด้วยว่าตัวอย่างที่ฉันให้ไว้ข้างต้นนั้นค่อนข้างแปลก
bricelam

ฉันสังเกตเห็นว่าพฤติกรรม OnDelete ดูเหมือนว่าจะมีให้เฉพาะใน API ที่คล่องแคล่วเท่านั้น คุณลองนึกดูว่าทำไมพวกเขาถึงเลือกทำแบบนี้? นี่คือสิ่งที่ฉันพยายามทำกับคำถามนี้ การละเมิด POCO อาจเป็นเหตุผลที่ดีหากคุณแบ่งปันชั้นเรียนระหว่างโครงการ คุณสามารถดึงเอนทิตี้ของกรอบงานเอนทิตี้ที่คุณไม่ต้องการถ้าคุณใช้คุณลักษณะ!
Tjaart

@ Tjaart ฉันจำเหตุผลไม่ได้แน่นอน ฉันเข้าร่วมทีมในตอนท้ายของฟีเจอร์ Code First และไม่ได้อยู่ที่การออกแบบนี้ ฉันจะดูว่าฉันสามารถรับคนอื่นจากทีมเพื่อชั่งน้ำหนักในว่า
bricelam

1

คำตอบสำหรับคำถามของคุณมีอยู่ในลิงค์

จากนั้นคุณกำหนดข้อ จำกัด ที่เกี่ยวข้องกับโดเมนของคุณภายในวิธีนี้โดยทางโปรแกรม

โดยทั่วไปจะมีการตั้งค่ามากกว่าหรือน้อยกว่าที่จะใช้ Attributes vs programmatic approach ซึ่งวิธีการเขียนโปรแกรมมีการควบคุมมากกว่าเอนทิตี อย่างไรก็ตามมีวิธีเพิ่มแอตทริบิวต์ในการตกแต่งแบบจำลองของคุณซึ่งคุณอาจมีลักษณะเช่นกัน

เมื่อใช้วิธีนี้คุณอาจอธิบายความสัมพันธ์ระหว่างตารางและคอลัมน์ ถ้าคุณเต็มใจที่จะควบคุมโดเมนของคุณอย่างละเอียดยิ่งขึ้นคุณสามารถใช้วิธีการใหม่นี้ที่มาพร้อมกับ EF4.1

อย่างไรก็ตามสำหรับสถานการณ์ทั่วไปของการตรวจสอบความถูกต้องของการใช้แอททริบิวต์ควรใช้งานได้ดีเพราะมีความทนทานในการครอบคลุมกรณีส่วนใหญ่ และนอกจากนี้มันอาจช่วยคุณประหยัดเวลา


คุณสามารถอธิบายได้ว่าวิธีการเขียนโปรแกรมช่วยให้คุณควบคุมได้มากขึ้นได้อย่างไร ฉันไม่ได้รับมัน ณ จุดนี้
Tjaart

ตัวอย่างเช่นใช้ ". IsConcurrencyToken (true)" - วิธีที่คุณจะทำสิ่งนี้ในนิยามของแอททริบิวต์?
Yusubov

[ConcurrencyCheck] <- ซึ่งจริง ๆ แล้วเรียบง่ายกว่านี้
Tjaart

คุณจะอธิบายความสัมพันธ์ระหว่างตารางและคอลัมน์อย่างไรดี?
Yusubov

[ForeignKey ("PersonId")] <- like so ซึ่งอาจไม่ตรงไปตรงมาเป็น. HasForeignKey (t => t.ProjectId) แม้ว่าสิ่งที่จำเป็นคือการให้ ForeignKey () ใช้แลมบ์ดาเหมือนกับอินเทอร์เฟซที่คล่องแคล่ว มันยังไม่ได้อธิบายว่าทำไมคนหนึ่งถึงดีกว่าคนอื่น
Tjaart

0

ความคิดของฉันคือพวกเขาแนะนำ API ได้อย่างคล่องแคล่วสำหรับการติดตั้งโค้ดครั้งแรกเพราะคุณอธิบายอย่างชัดเจนถึงวิธีการสร้างความสัมพันธ์ในฐานข้อมูล หากคุณใช้คำอธิบายประกอบข้อมูลฐานข้อมูลที่สร้างโดย Entity Framework อาจไม่ใช่สิ่งที่คุณคาดหวัง ตัวอย่างเริ่มต้นของคุณนั้นง่ายมากดังนั้นเช่นคุณฉันจะใช้วิธีการเพิ่มความคิดเห็น


คุณสามารถยกตัวอย่างของฐานข้อมูลไม่ได้เป็นสิ่งที่คุณคาดหวังและอินเทอร์เฟซที่คล่องแคล่วป้องกันสิ่งนี้เกิดขึ้นได้อย่างไร?
Tjaart
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.