2009-12-31 18 views
9

में एक घटक के रूप में एक अपरिवर्तनीय संरचना मैपिंग मैं एनएचबीर्नेट को मेरी कंपनी की ओआरएम जरूरतों का समाधान करने के लिए परीक्षण कर रहा हूं। ऐसा करने के लिए, मैंने स्कूल के आधार पर एक छोटा परीक्षण मॉडल तैयार किया है, जो एनएचबीर्नेट को संभालने के लिए कुछ उपयोगी एज-केस प्रदान करता है।NHibernate

मैं जानने IUserType इंटरफ़ेस का उपयोग किए बिना एक इकाई के एक घटक के रूप में एक कस्टम संरचना मैप करने के लिए कैसे समस्या आ रही है। मुझे इस बात पर जोर देना चाहिए कि यह एक महत्वपूर्ण आवश्यकता है कि डोमेन कक्षाएं हमारे एनएचबीरनेट कोड से अलग असेंबली में हों, और डोमेन असेंबली में एनएचबेर्नेट का संदर्भ नहीं है।

कस्टम संरचना Time है, जो दिन के कुछ घंटे और मिनटों का प्रतिनिधित्व करने के लिए उपयोग की जाती है। यह एक बहुत ही सरल अपरिवर्तनीय संरचना है और केवल कस्टम संरचना की समस्या को दर्शाने के लिए प्रदान की जाती है। कन्स्ट्रक्टर एक एकल तर्क लेता है जो hhmm रूप में एक पूर्णांक के रूप में घंटे और मिनट है।

CREATE TABLE Lessons 
(
    ID INT, 
    Subject NVARCHAR(128) 
    TeacherID INT, 
    Day VARCHAR(9), 
    StartTime INT, // <-- Maps to custom type. 
    Periods INT 
) 

:

public class Lesson 
{ 
    public int ID { get; private set; } 
    public Teacher Teacher { get; internal set; } 
    public DayOfWeek Day { get; set; } 
    public Time StartTime { get; set; } // <-- Custom Type 
    public int Periods { get; set; } 
} 

इस वर्ग इस तालिका को सीधे नक्शे:

public struct Time 
{ 
    public Time(int hoursAndMinutes) 
    { 
     // Initialize Structure // 
    } 

    public int Hours { get; private set; } 

    public int Minutes { get; private set; } 

    public int HoursAndMinutes { get; private set; } 
} 

यह संरचना दिन के समय स्टोर करने के लिए सबक शुरू होता है Lesson वर्ग के एक घटक के रूप में प्रयोग किया जाता है मैं इस संरचना को Lesson वर्ग के घटक के रूप में मानचित्रित करने का एक तरीका ढूंढ रहा हूं, ताकि एनएचबीर्नेट संरचना पर एक संपत्ति मूल्य (किसी अन्य घटक की तरह) पढ़ सके। o कॉलम के लिए मान प्राप्त करें, लेकिन कॉलम से इकाई को इकाई में मानते समय कन्स्ट्रक्टर को कॉलम मान पास करके संरचना का एक नया उदाहरण प्रारंभ करेगा।

यदि आपके पास कोई सुझाव है, तो यह सुपर होगा। यदि आप मुझे बताना चाहते हैं तो यह IUserType का उपयोग किए बिना पूरा नहीं किया जा सकता है, यह भी एक अच्छा जवाब है।

उत्तर

16

मेरे ज्ञान के लिए, हमले की तीन योजनाएं हैं।

  • आप सीधे कस्टम प्रकार के गुणों में घटक को मानचित्र बना सकते हैं। इस उदाहरण में, NHibernate HoursAndMinutes संपत्ति निर्धारित किया है, उचित रूप से Hours और Minutes गुण अद्यतन करने के लिए है कि संपत्ति के सेटर में कोड बदलने के लिए, और निर्माता है सिर्फ इसलिए एक ही कोड फोन this.HoursAndMinutes = hoursAndMinutes;Hours और Minutes गुण निष्पादित हो जाता है अद्यतन करने के लिए भले कन्स्ट्रक्टर का उपयोग किया जाता है या HoursAndMinutes संपत्ति पर सेटटर का उपयोग किया जाता है। क्या आप इसे इस तरह लिखेंगे यदि आप ओआरएम का उपयोग नहीं कर रहे थे और जानते थे कि यह उस संपत्ति के साथ डूबने जा रहा है? शायद ऩही। लेकिन यह दुनिया का अंत नहीं है और एक टिप्पणी सब कुछ समझाएगी।

  • आप IUserType या ICompositeUserType कार्यान्वयन लिखते हैं। वास्तव में, वे इस परिदृश्य के लिए ठीक है और संरचना को तत्काल करने के लिए आपको लचीलापन देते हैं, हालांकि आप NullSafeGet() कार्यान्वयन में कृपया डेटा को निकाल दें और डेटा को निकालें, हालांकि कृपया NullSafeSet() कार्यान्वयन में कृपया। यदि आप चाहें तो MyModel.NHibernateCrap.dll कहें, इसे किसी अन्य असेंबली में रखें। आपके मॉडल/डोमेन को यह पता होना आवश्यक नहीं है कि IUserType कार्यान्वयन या NHibernate मौजूद है - यह निर्दिष्ट करने के लिए मैपिंग फ़ाइल के लिए है।

  • आप अपने जवाब में मिकी वाट्स द्वारा वर्णित कोड-आधारित वर्कअराउंड का उपयोग करते हैं। यही है, एनएचबीर्नेट मैपिंग मानचित्र में आपके घटक के क्षेत्र में फ़ील्ड या निजी गुणों में आपका घटक जो कुछ जादू हाथ-पंखों को उन सार्वजनिक गुणों में परिवर्तित करने के लिए करते हैं जो एप्लिकेशन का उपयोग करते हैं, और इसके विपरीत। (यह मेरे द्वारा प्रदान किए जाने वाले पहले विकल्प के समान है; केवल अंतर यह है कि उनके परिदृश्य में यह क्षेत्र एक कामकाज है जो विरासत डेटाबेस को वर्ग कार्यान्वयन में रिसाव देता है, लेकिन आवेदन या मॉडल के अन्य हिस्सों में नहीं। छोटे, अलग मामलों के लिए , या यदि विरासत डेटाबेस सिर्फ जीवन का एक तथ्य है, तो मुझे लगता है कि यह पूरी तरह से उचित है।)

सीधे और वास्तविक आपके प्रश्न का उत्तर करने के लिए, NHibernate एक निर्माता पैरामीटर है कि कॉल करने के लिए नहीं जा रहा है, अवधि - यह बस यह काम करता है कि यह कैसे काम करता है, यह एक वस्तु को समाचार देता है और फिर उस पर सेटिंग और प्रतिबिंबित करना शुरू करता है - जब तक कि आप प्रॉक्सी के साथ अजीब चीजें करना शुरू न करें या इसे अपने IUserType कार्यान्वयन का उपयोग करने के लिए कहें। मैपिंग फ़ाइल या उसके जैसा कुछ भी <constructor><arg>HoursAndMinutes</arg></constructor> जैसे कुछ कहने के लिए कोई तंत्र नहीं है। चिंता करना बंद करो और बम से प्यार करो।

चूंकि IUserType ऐसी चीजों को करने के लिए एनएचबेर्नेट द्वारा प्रदान की गई तंत्र है, मैं वास्तव में समझ नहीं पा रहा हूं कि कोई इसका उपयोग क्यों नहीं करना चाहता।

शुभकामनाएं!

+0

अच्छी जानकारी; आपके लिए +1 IUserType का उपयोग न करने की मेरी आवश्यकता यह देखने के लिए है कि वहां कौन से विकल्प उपलब्ध हैं, जिन्हें आपने कृपापूर्वक प्रदान किया है। –

+0

निकोलस - यदि हमारे पास ऐसी संरचनाएं हैं जिनमें इकाई प्रकार (मान प्रकारों के विपरीत) शामिल हैं, तो क्या हम इन्हें IUserType के साथ मैप कर सकते हैं? यदि हां, तो कैसे; यदि नहीं, तो विकल्प क्या है? – fostandy

2

मैं प्राथमिकता ईआरपी पर आधारित एक विरासत डेटाबेस के साथ काम कर रहा हूं। डेटाबेस में, समय को एक युग से शुरू होने वाले मिनटों की पूर्णांक संख्या के रूप में दर्शाया जाता है। तो उदाहरण के लिए, संख्या 0 01/01/1988 00:00 का प्रतिनिधित्व करती है, और संख्या 1440 02/01/1988 00:00 और इसी तरह का प्रतिनिधित्व करती है।

समाधान है कि मैं इस के लिए मिला था इस तरह दिखता है:

[Field("CURDATE")] 
    private int transactionDate = DateTimeHelper.ConvertToInternalValue(DateTime.Today); 

    public DateTime TransactionDate 
    { 
     get { return DateTimeHelper.ConvertToDateValue(transactionDate); } 
     set { transactionDate = DateTimeHelper.ConvertToInternalValue(value); } 
    } 

जहां DateTimeHelper पर कार्यों वास्तविक मिनट के पूर्णांक संख्या से एक वास्तविक दिनांक समय संरचना को बदलने है।

+0

जवाब के लिए धन्यवाद, लेकिन इस काम का एक विशुद्ध रूप से सैद्धांतिक टुकड़ा सीमा जा सकता है ओआरएम उपकरण का। मैपिंग अपरिवर्तनीय संरचनाओं को चित्रित करने के लिए गैर मानक प्रारूप में समय चुना गया था। काम करने के लिए मज़ेदार काम, सीधे सवाल का जवाब नहीं दे रहे हैं। –

0

संरक्षित सेट और उस पर एक संरक्षित डिफ़ॉल्ट निर्माता करने के लिए मुझे

इस तरह काम करने के लिए लग रहा था:

public struct Time 
{ 
    protected Time(){} 
    public Time(int hoursAndMinutes) 
    { 
     // Initialize Structure // 
    } 

    public int Hours { get; protected set; } 

    public int Minutes { get; protected set; } 

    public int HoursAndMinutes { get; protected set; } 
} 
+0

यह कैसे काम करता है? जब मैं संरचना के लिए एक खाली कन्स्ट्रक्टर बनाता हूं तो मुझे संकलन त्रुटि मिलती है "संरचना में पैरामीटर रहित कन्स्ट्रक्टर नहीं हो सकता"। –