อะไรคือข้อผิดพลาดที่พบบ่อยที่สุดและรูปแบบการต่อต้านที่ผู้ใช้โปรแกรมเมอร์ของ NHibernate ทำ?


28

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

ตัวอย่างเช่น:

  • การต่อต้านแบบหนึ่งที่พบได้ทั่วไปสำหรับโปรแกรมเมอร์ NHibernate ใหม่คือการใช้เอกลักษณ์ / ดั้งเดิม POID แทนการใช้ออร์มสไตล์ ORM อ่านเพิ่มเติมได้ที่นี่ ...

1
คุณสามารถพบข้อผิดพลาดทั่วไปบางอย่างได้ที่นี่: NHProf Alerts

1
นอกจากนี้ยังมีโพสต์ที่มีค่าบางอย่างเกี่ยวกับข้อผิดพลาดของ NHibernate

คำตอบ:


34

ปัญหา "อธิบายบ่อย" ส่วนบุคคลของฉัน:

ต่อต้านรูปแบบ

ล้อเล่นรอบวัตถุที่ถูกดึงออกมา (SaveOrUpdate หรือผสานรวมกับรหัสยุ่ง ๆ ) แทนที่จะใช้ DTO เอนทิตีที่ซับซ้อนยิ่งกว่านั้นรหัสก็จะยุ่งยิ่งขึ้น (มันยังหมายความว่ามันทำงานได้ค่อนข้างดีกับเอนทิตี้เล็ก ๆ น้อย ๆ ) Ayende เรียกมันว่าStripper Patternและอธิบายปัญหาการห่อหุ้ม

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

  • ฉันพยายามอธิบายในคำตอบ SO นี้
  • อ่านวิธีการล้างผลงานในเอกสารอ้างอิง
  • บล็อกโพสต์โดย kurtharrigerที่ถูกวิจารณ์ว่าสิ่งที่เป็นจริงหนึ่งในคุณสมบัติหลัก (ในฐานะพิสูจน์ว่ามันเป็นความเข้าใจผิดกันเกี่ยวกับ NH)

ไม่เข้าใจธุรกรรมและหน่วยของรูปแบบการทำงาน รูปแบบการต่อต้านเป็นประจำ: ธุรกรรมโดยนัย, เซสชันต่อการดำเนินงานและเซสชันต่อแอปพลิเคชัน อ่านเพิ่มเติม:

การใช้กิจกรรม NH เพื่อใส่ตรรกะของแอปพลิเคชันใน (เช่นการเปลี่ยนแปลงการติดตามในทริกเกอร์การแทรกและการอัปเดต)

สร้างชั้นหนึ่งต่อโต๊ะ บางคนไม่เข้าใจ OOD บางคนไม่เข้าใจการออกแบบเชิงสัมพันธ์

ข้อผิดพลาด

ใช้แบบหนึ่งต่อหนึ่งแทนแบบตัวต่อตัว ฉันพยายามอธิบายในคำตอบนี้

การใช้การดึงข้อมูลเข้าร่วมพร้อมกับ SetMaxResult คำตอบล่าสุดของฉันที่เกี่ยวข้องกับหัวข้อนั้น:

เขียนหน่วยงานที่มีการเปลี่ยนแปลงตัวเอง เมื่อเอนทิตีไม่ส่งคืนค่าที่ตั้งไว้โดย NH อย่างแน่นอนจะถือว่าสกปรกและได้รับการอัปเดตในทุกเซสชัน ตัวอย่างเช่น: การแทนที่คอลเลกชันถาวร NH ใน setter คุณสมบัติ

  IList<Address> Addresses
  {
    get { return addresses; }
    // will cause the addresses collection to be built up from scratch
    // in the database in every session, even when just reading the entity.
    set { addresses = new List<Address>(value); }
  }

  int Whatever
  {
    // will make the entity dirty after reading negative values from the db.
    // this causes unexpected updates after just reading the entity.
    get { if (whatever < 0) return 0; }
    set { whatever = value; }
  }

อาจจะมากขึ้นกำลังติดตาม


2
+1: คุณควรเพิ่ม "ไม่ใช้รูปแบบหน่วยการทำงาน" และ "หนึ่งเซสชันต่อแอปพลิเคชัน" ในรายการของคุณ
Falcon

@ เหยี่ยว: ใช่อาจ เป็นปัญหาทั่วไปที่ "ไม่เข้าใจธุรกรรม" หน่วยงานเป็นบิตที่ปกคลุมด้วยความไม่รู้ความเพียร แม้ว่าพวกเขาจะมีแนวคิดที่แตกต่างอย่างสิ้นเชิง แต่พวกเขาส่งผลในรูปแบบเดียวกัน
Stefan Steinegger

5

ปัญหา " เลือก N + 1 "

นี่คือที่ที่คุณท้ายการดำเนินการ A เลือกสำหรับแต่ละเอนทิตีที่คุณต้องการจัดการ (N) และเลือกเพื่อรับรายการเอนทิตี (+1) แทนที่จะเลือกเดี่ยวของเอนทิตีทั้งหมดและคุณลักษณะของพวกเขา


1
  • มีบทคัดย่อมากเกินไป
  • ไม่ได้ใช้ Automappings กับ FluentNHibernate

จุดแรกนั้นค่อนข้างคลุมเครือ แต่ในกรณีที่คุณอ้างถึงความคิดที่โง่เขลาเช่นการซ่อน ISession ไว้เบื้องหลัง "Repository" หรือ "DAO" ฉันเห็นด้วย
chris

1
จุดที่สองคือเรื่องไร้สาระ มีเหตุผลที่ดีว่าทำไมเรามักต้องการควบคุมแบบจำลองข้อมูลทางกายภาพอย่างละเอียดและสามารถแยกออกจากแบบจำลองโดเมนได้ ท้ายที่สุดนั่นคือจุดของ "M" ใน "ORM" การใช้ automappings (ในขณะที่มีประโยชน์ในสถานการณ์ง่าย ๆ ) จะเอาชนะมันได้ นอกจากนี้ยังมีปัญหาของสกีมาฐานข้อมูลระบบเดิมซึ่งการทำแผนที่อัตโนมัตินั้นไม่มีประโยชน์
chris

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

1

พยายามสรุปออกมาเพื่อให้คุณสามารถเปลี่ยนเป็น Entity Framework (หรืออย่างอื่น) ได้ในภายหลัง

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

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

หากมีความต้องการที่ถูกต้องในการสลับระหว่าง NHibernate และ Entity Framework ก็จะมีโครงการที่พัฒนาขึ้นเพื่อสนับสนุนสิ่งนี้บน GitHub (อาจเป็นสิ่งที่คล้ายกันใน CommonServiceLocator) กับผู้ให้ข้อมูลจำนวนมากและคำขอดึง

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