2010-11-05 9 views
5

का उपयोग कर कोई सेटटर वाला रीड-ओनली प्रॉपर्टी मैप करना मेरे पास ऐसा डोमेन क्लास है जो इस तरह दिखता है। मैं NH12ern51 से को LastUpdate के वर्तमान मूल्य को सहेजने/अपडेट करने के दौरान सहेजता हूं ताकि मैं इसे प्रश्नों में उपयोग कर सकूं, लेकिन डेटाबेस से Foo पुनर्प्राप्त करते समय इसे अनदेखा कर सकूं और जब मैं वास्तव में इसे एक्सेस करता हूं तो ऑब्जेक्ट स्वयं मान को फिर से समझने दें।Fluent NHibernate

public class Foo { 
    public DateTime LastUpdate { 
     get { 
      /* Complex logic to determine last update by inspecting History */ 
      return value; 
     } 
    } 
    public IEnumerable<History> History { get; set; } 
    /* etc. */ 
} 

Foo के लिए मेरे मानचित्रण इस तरह दिखता है:

public class FooMap : ClassMap<Foo> { 
    Map(x => x.LastUpdate) 
     .ReadOnly(); 
    HasMany(x => x.History); 
    // etc... 
} 

मैंने सोचा था कि ReadOnly() क्या मैं इसे पूरा करना चाहता था, लेकिन जब मैं एक SessionFactory मैं निम्नलिखित अपवाद बनाने का प्रयास करें:

Error: FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
---> NHibernate.PropertyNotFoundException: Could not find a setter for property 'LastUpdate' in class 'Foo'.

संपत्ति में कोई सेटटर नहीं है क्योंकि इसे सेट नहीं किया जाना चाहिए, केवल से पढ़ें। ReadOnly() क्या करने के लिए सही बात है? यदि नहीं, तो क्या?

(NHibernate v3.0b1, धाराप्रवाह NHibernate v1.1)

+0

ReadOnly() ; जेनरेट किए गए मैपिंग एक्सएमएल में केवल सेट्स = "झूठी" और LastUpdate प्रॉपर्टी के अद्यतन = "झूठे" गुणों को स्ट्रीम करता है। – tolism7

उत्तर

12

ReadOnly Fluent का निर्देश NHibernate इस संपत्ति पर परिवर्तनों की तलाश नहीं करने के लिए, यह संकलक-दुनिया में केवल पढ़ने योग्य संपत्ति के बराबर नहीं है। आपकी संपत्ति केवल एनएचबेर्नेट की आंखों में पढ़ी नहीं जाती है क्योंकि आप उम्मीद कर रहे हैं कि यह आपके डेटाबेस से पॉप्युलेट हो। आपको क्या करना है एनएचबीर्नेट को बताएं कि उसे उस संपत्ति के मूल्य को एक निजी क्षेत्र के माध्यम से उसी नाम (लोअरकेड) के साथ संपत्ति के रूप में एक्सेस करना चाहिए।

Map(x => x.LastUpdate) 
    .Access.Field(); 

Field का उपयोग कर, जो एक आप कैसे आप अपने निजी क्षेत्रों के नाम पर निर्भर करेगा का उपयोग करने के कई विकल्प हैं।

+2

मैं वास्तव में डेटाबेस से डेटाबेस को पॉप्युलेट नहीं करना चाहता हूं, इसकी गणना गेटर में गतिशील रूप से की जाती है। मैं बस इसे डेटाबेस में सहेजना चाहता हूं ताकि मैं इसके खिलाफ पूछ सकूं। –

+6

यदि निबर्ननेट इसे पॉप्युलेट नहीं करता है, तो उसे सहेजना नहीं होगा क्योंकि यह पता नहीं है कि मूल्य कब बदलता है। प्रस्तावित दोनों समाधान बिल्कुल वही हैं और आपने जो वर्णन किया है वह करें। NHibernate क्षेत्र द्वारा चर का उपयोग कर सकते हैं ताकि आपको एक सेटर की आवश्यकता न हो। जब आप गेटटर तक पहुंचते हैं तो मूल्य की गणना गतिशील रूप से की जाएगी। जब आप अपडेट करते हैं तो NHibernate मान को सहेज लेगा। तथ्य यह है कि NHBernate इसे डीबी से पॉप्युलेट करता है, अप्रासंगिक होना चाहिए - जब तक आप पहुंच नहीं पाते, आपको पता नहीं होता/देखभाल करते हैं, जब आप इसे एक्सेस करते हैं तो मूल्य की गणना की जाएगी। निबर्ननेट द्वारा "प्रारंभिक" के रूप में देखें यदि यह मदद करता है। – Sisyphus

+0

@ सिसिफस वह स्पष्टीकरण बहुत मदद करता है। धन्यवाद। –

2

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

नियमित एचबीएम में आप केवल एक्सेस = फ़ील्ड को मानचित्र करेंगे। हर कोई यह करता है। जाहिर है फ्लुएंट एक साधारण नहीं है। मैं धाराप्रवाह का उपयोग नहीं करते ...

संपादित करें ...

लगता है जो कुछ भी मानचित्रण निजी समर्थन क्षेत्रों के लिए उचित रूप में हमेशा अस्थिर लक्ष्य अपने संस्करण में है और कि का उपयोग करें ...

+1

फ्लुएंट एनएचबेर्नेट में यह उतना आसान है: 'मानचित्र (x => x.LastUpdate)। असफल।फ़ील्ड() ' –

0

बस अपने वर्ग के लिए एक खाली निजी सेटर जोड़ें:

 private set { } 

मैं भी एक विशेषता और अपने इरादे दस्तावेज़ के लिए एक टिप्पणी जोड़ने (और ReSharper को खुश करने के):

 [UsedImplicitly] 
     // ReSharper disable once ValueParameterNotUsed 
     private set { } 
संबंधित मुद्दे