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

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

ทำความเข้าใจกับปัญหา

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

  • AcceptedPlan: แทนแผนการชำระเงินที่ลูกค้ารับรอง
  • Plan: แทนรายละเอียดการอ้างอิงของแผนการชำระเงิน

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

วิธีแก้ปัญหาที่เสนอ

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

หลีกเลี่ยงความซับซ้อนที่ไม่จำเป็น

แทนที่จะมีวัตถุเด็ก (AcceptedPlan) อ้างอิงไปยังวัตถุหลัก (Plan) โดยตรง คุณสามารถจัดการการอ้างอิงผ่าน ID ได้ วิธีการนี้ช่วยป้องกันปัญหาที่เกี่ยวข้องกับการวนลูปและทำให้แบบจำลองโดเมนของคุณสะอาดขึ้น

การแมพแบบทีละขั้นตอน

  1. กำหนดคลาส Customer

    ขั้นตอนแรกคือการกำหนดคลาส Customer และแมพไปยังตาราง details กระเป๋า AcceptedOffers จะเป็นตัวแทนของข้อเสนอที่ลูกค้ารับรองหลายรายการ

    <hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
        <class lazy="false" name="Namespace.Customer, Namespace" table="Customer">
            <id name="Id" type="Int32" unsaved-value="0">
                <column name="CustomerAccountId" length="4" sql-type="int" not-null="true" unique="true" index="CustomerPK"/>
                <generator class="native" />
            </id>
            <bag name="AcceptedOffers" inverse="false" lazy="false" cascade="all-delete-orphan" table="details">
                <key column="CustomerAccountId" foreign-key="AcceptedOfferFK"/>
                <many-to-many
                    class="Namespace.AcceptedOffer, Namespace"
                    column="AcceptedOfferFK"
                    foreign-key="AcceptedOfferID"
                    lazy="false"
                />
            </bag>
        </class>
    </hibernate-mapping>
    
  2. กำหนดคลาส AcceptedOffer

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

    <hibernate-mapping default-cascade="save-update" xmlns="urn:nhibernate-mapping-2.2">
        <class lazy="false" name="Namespace.AcceptedOffer, Namespace" table="AcceptedOffer">
            <id name="Id" type="Int32" unsaved-value="0">
                <column name="AcceptedOfferId" length="4" sql-type="int" not-null="true" unique="true" index="AcceptedOfferPK"/>
                <generator class="native" />
            </id>
            <many-to-one 
                name="Plan"
                class="Namespace.Plan, Namespace"
                lazy="false"
                cascade="save-update"
            >
                <column name="PlanFK" length="4" sql-type="int" not-null="false"/>
            </many-to-one>
            <property name="StatusId" type="Int32">
                <column name="StatusId" length="4" sql-type="int" not-null="true"/>
            </property>
        </class>
    </hibernate-mapping>
    

ข้อคิดสำคัญ

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

บทสรุป

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