Entity Framework Code First - ข้อดีและข้อเสียของ Fluent Api เทียบกับ Data Annotations [ปิด]


120

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

ข้อดีและข้อเสียของ Fluent Api เมื่อเปรียบเทียบกับ Data Annotations คืออะไร? กล่าวอีกนัยหนึ่ง: แม้ว่าในบางสถานการณ์สามารถใช้ทั้งสองวิธีได้ แต่ในกรณีใดวิธีหนึ่งควรมีชัยเหนืออีกวิธีหนึ่ง?


3
เพียงแค่ความคิด: สิ่งที่ฉันมักจะทำคือสร้างโครงการ Model ด้วย POCO ของฉันจากนั้นในโครงการ Repository สร้าง POCO ชุดใหม่สำหรับ EF โดยเฉพาะและใส่คำอธิบายประกอบของฉันไว้ที่นั่น จากนั้นฉันก็แมประหว่างทั้งสองในคลาสนักทำแผนที่ ด้วยวิธีนี้โมเดลของฉันจะไม่ถูกแตะต้องและทำให้ง่ายต่อการเพิ่ม / เปลี่ยนแปลงกลยุทธ์ข้อมูลของฉันหากจำเป็น (เช่นเพิ่ม XmlRepository และใช้คลาส Model เดียวกัน)
adimauro

1
ตอนนี้ฉันชอบคำอธิบายประกอบกับ EFCore และไลบรารีเพิ่มเติม (ต้องใช้รหัสน้อยกว่าและทั้งหมดอยู่ในที่เดียว) github.com/isukces/EfCore.Shaman - เพิ่มและขยายแอตทริบิวต์github.com/borisdj/EFCore.FluentApiToAnnotation - มีประโยชน์เมื่อมี DB อยู่แล้วหลังจากทำ Reverse-Engineering และเปลี่ยนเป็น CodeFirst
borisdj

คำตอบ:


142

ทุกสิ่งที่คุณสามารถกำหนดค่าด้วย DataAnnotations เป็นไปได้ด้วย Fluent API การย้อนกลับไม่เป็นความจริง ดังนั้นจากมุมมองของตัวเลือกการกำหนดค่าและความยืดหยุ่น Fluent API จึง "ดีกว่า"

ตัวอย่างการกำหนดค่า (แน่นอนว่าไม่ใช่รายการทั้งหมด) ซึ่งเป็นไปได้ใน Fluent API แต่ไม่ใช่กับ DataAnnotations (เท่าที่ฉันเห็น):

  • ปิดการลบแบบเรียงซ้อน:

    .WillCascadeOnDelete(false)

  • ระบุชื่อคอลัมน์คีย์ต่างประเทศในฐานข้อมูลเมื่อคีย์ไม่ถูกเปิดเผยในโมเดลอ็อบเจ็กต์ของคุณ:

    .Map(conf => conf.MapKey("MyForeignKeyID"))

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

    .WithMany(...), WithOptional(...), WithRequiredDependent(...),WithRequiredPrincipal(...)

  • ข้อมูลจำเพาะของการแมปมรดกระหว่างโมเดลออบเจ็กต์และตารางฐานข้อมูล (Table-Per-Hierarchy, Table-Per-Type, Table-Per-Concrete-Class):

    .Map<TDerived>(Action<EntityMappingConfiguration<TDerived>> ...)

แก้ไข: Microsoft ถือว่า Fluent API เป็น "คุณลักษณะขั้นสูง" (อ้างอิงจากที่นี่ ):

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

แต่ในความคิดของฉันคุณเข้าถึงข้อ จำกัด ของ DataAnnotations ได้เร็วมาก (ยกเว้นบางทีสำหรับโมเดลวัตถุที่เรียบง่ายมาก) หากคุณไม่สามารถปรับแต่งแบบจำลองของคุณด้วย DataAnnotations ได้อีกต่อไปทางเลือกสุดท้ายของคุณคือการปฏิบัติตามข้อกำหนดการทำแผนที่เริ่มต้น (โดยการตั้งชื่อคุณสมบัติของคุณตามกฎเหล่านั้น) ขณะนี้คุณไม่สามารถเขียนทับอนุสัญญาได้ (ปิดใช้งานเท่านั้น MS ประกาศว่าจะให้ตัวเลือกการกำหนดค่าสำหรับอนุสัญญาในรุ่น EF ในอนาคต) แต่ถ้าคุณไม่ต้องการถูกบังคับโดยรูปแบบการทำแผนที่เมื่อคุณกำหนดรูปแบบวัตถุของคุณตัวเลือกเดียวของคุณก็คือ Fluent API

การเรียนรู้ Fluent API นั้นแทบจะเป็นสิ่งที่ต้องทำ แต่ DataAnnotations เป็นสิ่งที่ดีสำหรับแอปพลิเคชันง่ายๆ


2
ฉันเป็นมือใหม่ในด้านนี้ Fluent API สามารถใช้เพื่อตรวจสอบอินเทอร์เฟซผู้ใช้แบบที่ DataAnnotation ทำได้หรือไม่
จูบรักแร้

27
@CounterTerrorist: ฉันไม่คิดอย่างนั้น ตัวอย่างเช่น: หากคุณใส่[Required]แอตทริบิวต์บนคุณสมบัติในแอปพลิเคชัน ASP.NET MVC จะถูกใช้ทั้งโดย EF และโดย MVC เพื่อวัตถุประสงค์ในการตรวจสอบความถูกต้องเนื่องจากทั้งสองสามารถประมวลผลแอตทริบิวต์นี้ได้ แต่ MVC จะไม่เข้าใจการกำหนดค่า Fluent API ดังนั้นหากคุณลบแอตทริบิวต์และใช้HasRequiredใน Fluent API แทนสำหรับ EF จะเหมือนกัน แต่ไม่ใช่สำหรับ MVC (ในความคิดของฉันแอตทริบิวต์ควรได้รับการตั้งชื่อที่แตกต่างกันการใช้เนมสเปซ DataAnnotations จากส่วนประกอบที่แตกต่างกันและเพื่อวัตถุประสงค์ที่แตกต่างกันนั้นสับสนมาก)
Slauma

4
นอกจากนี้ยัง[DefaultValue()]ไม่สามารถทำได้ใน Fluent Either
webnoob

4
MinValue เป็นแอตทริบิวต์ที่ไม่สามารถกำหนดผ่าน Fluent API (Programming Entity Framework: Code First) (ที่มา: ลบ NAA โดยThe Cog )
Serge Ballesta

7
จากมุมมองทางสถาปัตยกรรมฉันเดาว่าFluent APIจะรักษาตรรกะในการใช้งานของคุณDbContextและรักษาความPOCOสะอาด
Luke T O'Brien
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.