ฉันสงสัยเพราะถ้าเป็นเช่นนั้นเหตุใด Entity Framework จึงไม่มีเหตุผลในการสร้างวัตถุใหม่ที่มีคุณสมบัติเดียวกันเพื่อถ่ายโอนข้อมูลระหว่างเลเยอร์
ฉันใช้วัตถุเอนทิตีที่ฉันสร้างขึ้นด้วยกรอบงานเอนทิตี
ฉันสงสัยเพราะถ้าเป็นเช่นนั้นเหตุใด Entity Framework จึงไม่มีเหตุผลในการสร้างวัตถุใหม่ที่มีคุณสมบัติเดียวกันเพื่อถ่ายโอนข้อมูลระหว่างเลเยอร์
ฉันใช้วัตถุเอนทิตีที่ฉันสร้างขึ้นด้วยกรอบงานเอนทิตี
คำตอบ:
มันขึ้นอยู่กับคุณ.
คนส่วนใหญ่จะบอกคุณว่ามันไม่ใช่วิธีปฏิบัติที่ดี แต่คุณสามารถหลีกเลี่ยงได้ในบางกรณี
EF ไม่เคยเล่น DDD อย่างดีด้วยเหตุผลหลายประการ แต่มีสองอย่างที่โดดเด่น: คุณไม่สามารถสร้างพารามิเตอร์ในเอนทิตีของคุณและคุณไม่สามารถแค็ปซูลคอลเลกชัน DDD ขึ้นอยู่กับว่าเนื่องจากรูปแบบโดเมนควรมีทั้งข้อมูลและพฤติกรรม
ในอีกทางหนึ่ง EF บังคับให้คุณมีรูปแบบโดเมนโลหิตจางและในกรณีนี้คุณสามารถใช้เอนทิตีเป็น DTO ได้ คุณอาจพบปัญหาบางอย่างถ้าคุณใช้คุณสมบัติการนำทาง แต่คุณสามารถซีเรียลเอนทิตีเหล่านั้นและส่งพวกเขาผ่านสาย มันอาจไม่สามารถใช้งานได้จริง คุณจะต้องควบคุมการทำให้เป็นอันดับสำหรับแต่ละเอนทิตีที่มีคุณสมบัติที่คุณไม่จำเป็นต้องส่ง วิธีที่ง่ายกว่าคือการออกแบบคลาสแยกต่างหากที่ออกแบบมาเพื่อการถ่ายโอนข้อมูล ไลบรารีเช่นAutoMapperถูกสร้างขึ้นเพื่อจุดประสงค์นี้
ตัวอย่างเช่นสมมติว่าคุณมีคลาสที่ถูกเรียกPerson
พร้อมกับคำจำกัดความต่อไปนี้:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; get; }
// plus a bunch of other properties relevant about a person
}
สมมติว่าคุณต้องการที่จะแสดงรายชื่อของพนักงานบางแห่งก็อาจจะเป็นในทางปฏิบัติที่จะส่งเพียงId
, และFirstName
LastName
แต่คุณจะต้องส่งมอบคุณสมบัติที่ไม่เกี่ยวข้องอื่น ๆ ทั้งหมด ไม่ใช่เรื่องใหญ่หากคุณไม่สนใจขนาดของการตอบกลับ แต่แนวคิดทั่วไปคือการส่งข้อมูลที่เกี่ยวข้อง ในทางกลับกันคุณอาจออกแบบ API ที่ส่งคืนรายชื่อบุคคลและในกรณีนั้นการส่งคุณสมบัติทั้งหมดอาจจำเป็นต้องใช้ดังนั้นจึงควรทำให้ซีเรียลไลซ์และส่งเอนทิตี ในกรณีนี้การสร้างคลาส DTO นั้นเป็นที่ถกเถียงกัน บางคนชอบผสมเอนทิตีและ DTO บางคนทำไม่ได้
เพื่อตอบคำถามที่อัปเดตของคุณ EF คือ ORM หน้าที่ของมันคือการแมปบันทึกฐานข้อมูลกับวัตถุและในทางกลับกัน สิ่งที่คุณทำกับวัตถุเหล่านั้นก่อนและหลังผ่าน EF ไม่ใช่ส่วนหนึ่งของข้อกังวล ไม่ควรจะเป็น
ไม่มันไม่ใช่.
ตามหลักการแล้ว DTO จะตรงกับที่เก็บข้อมูลของคุณ (เช่นตารางฐานข้อมูลของคุณ)
แต่คลาสธุรกิจของคุณไม่จำเป็นต้องตรงกัน คุณอาจต้องการคลาสเพิ่มเติมหรือแยกหรือเข้าร่วมคลาสกับสิ่งที่คุณมีในฐานข้อมูล หากแอปพลิเคชันของคุณมีขนาดเล็กคุณอาจไม่เห็นปัญหาเช่นนี้ แต่ในแอปพลิเคชันขนาดกลางถึงขนาดใหญ่สิ่งนี้จะเกิดขึ้นบ่อยครั้ง
อีกสิ่งหนึ่งคือ DTO นั้นเป็นส่วนหนึ่งของโดเมนของทุกสิ่งที่เกี่ยวข้องกับการคงอยู่ในขณะที่ชั้นธุรกิจของคุณไม่ควรรู้อะไรเลย
จริงๆแล้วมันเป็นความคิดที่แย่มาก ๆ ฟาวเลอร์มาร์ตินมีบทความเกี่ยวกับ DTOs
เรื่องสั้นที่มีความยาวDTO
รูปแบบถูกใช้สำหรับการถ่ายโอนข้อมูลนอกกระบวนการตัวอย่างเช่นบนเส้นลวดและไม่ใช่ระหว่างเลเยอร์ภายในกระบวนการเดียวกัน
ไม่มันเป็นการปฏิบัติที่ไม่ดี
เหตุผลบางอย่าง:
@JsonIgnore
จากโลกของ Java) แต่สิ่งนี้นำไปสู่ปัญหาต่อไป ...get
วิธีการของเอนทิตีดังนั้นจึงง่ายขึ้นและปลอดภัยใช้เครื่องมือ mapper บางชนิดเพื่อช่วยคุณในงานนี้การแมปเขตข้อมูลเอนทิตีกับ Dto
เพื่อให้สิ่งที่ @Dherik พูดถึงเสร็จสมบูรณ์ปัญหาหลักของการใช้วัตถุเอนทิตีเป็นวัตถุการถ่ายโอนข้อมูลคือ:
ในธุรกรรมคุณมีความเสี่ยงที่จะยอมรับการเปลี่ยนแปลงที่ทำกับเอนทิตีของคุณเพราะคุณใช้มันเป็น DTO (แม้ว่าคุณจะสามารถแยกเอนทิตี้ของเซสชันในการทำธุรกรรมได้ส่วนใหญ่คุณจะต้องตรวจสอบสถานะนี้ก่อน การปรับเปลี่ยนใด ๆ ใน DTO ของคุณและรับรองว่าคุณไม่ได้ทำธุรกรรมหรือปิดเซสชันหากคุณไม่ต้องการให้มีการแก้ไข)
ขนาดของข้อมูลที่คุณแชร์ระหว่างไคลเอนต์และเซิร์ฟเวอร์: บางครั้งคุณไม่ต้องการส่งเนื้อหาทั้งหมดของเอนทิตีไปยังไคลเอนต์เพื่อลดขนาดของการตอบสนองของคำขอ การแยก DTO ออกจากเอนทิตีนั้นมีความยืดหยุ่นมากขึ้นเพื่อที่จะเชี่ยวชาญข้อมูลที่คุณต้องการส่งในกรณีใช้งานบางอย่าง
ทัศนวิสัยและการบำรุงรักษา: คุณต้องจัดการคำอธิบายประกอบ jpa / hibernate ในช่องของเอนทิตีของคุณและเก็บรักษาคำอธิบายประกอบแจ็คสันเพื่อทำให้เป็นอนุกรมใน json ที่สถานที่เดียวกัน (แม้ว่าคุณสามารถแยกพวกเขาออกจากการใช้งานเอนทิตี นิติบุคคล) จากนั้นหากคุณเปลี่ยนเนื้อหา DTO ของคุณในการเพิ่มฟิลด์ใหม่บุคคลอื่นอาจคิดว่าเป็นฟิลด์ของเอนทิตีดังนั้นฟิลด์ของตารางที่เกี่ยวข้องกับฐานข้อมูลของคุณ (แม้ว่าคุณจะสามารถใช้@Transient
คำอธิบายประกอบในฟิลด์ DTO ทั้งหมดของคุณ สำหรับกรณี .. !)
ในความคิดของฉันมันจะสร้างเสียงรบกวนเมื่อคุณอ่านเอนทิตี แต่ความเห็นของฉันเป็นแบบอัตนัย