2009-07-13 15 views
9
साथ इकाई प्रकार पर तरीकों की उपेक्षा कर

मैं इस तरह एक वर्ग कुछ मिल गया है:nHibernate

public class Account 
{ 
    public virtual int Id { get; private set; } 
    public virtual string Username { get; set; } 

    [EditorBrowsable(EditorBrowsableState.Never)] 
    public virtual string Password { get; private set; } 

    public void SetPassword(string password){ ... } 
    public bool CheckPassword(string password) { ... } 
} 

मैं इसे इस तरह से सेट कर लिए जाने के बाद से मैं नहीं है कभी Password संपत्ति कोड में सीधे उपयोग करना चाहते हैं Account प्रकार का उपयोग करता है। खाता नक्शा इस तरह दिखता है:

public class AccountMap : ClassMap<Account> 
{ 
    public AccountMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Username); 
     Map(x => x.Password); 
    } 
} 

जब मैं वास्तव में NHibernate के साथ इस का उपयोग मैं एक InvalidProxyTypeException

NHibernate.InvalidProxyTypeException: The following types may not be used as proxies: 
    Fringine.Users.Account: method SetPassword should be virtual 
    Fringine.Users.Account: method CheckPassword should be virtual 

मैं समझता हूँ कि NHibernate और आलसी लोड हो रहा है समर्थन करने के लिए एक प्रॉक्सी वर्ग बनाने के लिए कोशिश कर रहा है कि मिल मैं या तो अपवाद को हल करने के लिए मानचित्र में वर्चुअल को Not.LazyLoad() जोड़ने के तरीकों को चिह्नित कर सकता हूं। लेकिन - मैं उनमें से किसी एक को नहीं करना चाहता हूं। मैं आलसी लोडिंग का समर्थन करना चाहता हूं लेकिन मुझे नहीं लगता कि उन तरीकों को वर्चुअल होने की आवश्यकता क्यों है।

क्या NHibernate (या आंतरिक रूप से कैसल आंतरिक रूप से) निर्धारित करने के लिए विधि का उपयोग करता है कि कौन से फ़ील्ड का उपयोग किया जाता है और उन गुणों के लिए आलसी लोडिंग को अनुकूलित किया जाता है? यदि नहीं, तो विधि के संदर्भ में विधि को आभासी होने की आवश्यकता क्यों है और जब वे विधि द्वारा संदर्भित होते हैं तो वे आलसी लोड हो जाएंगे।

क्या वर्चुअल आवश्यकता से कुछ विधियों को बाहर करने का कोई तरीका है?

उत्तर

7

कारण यह है कि आप अपने तरीकों, जो आरंभ नहीं किया जा जाएगा में खेतों का उपयोग कर सकता है। तो ऑब्जेक्ट को किसी भी कॉल पर इकाई की सामग्री को लोड करना सबसे आसान तरीका है (केवल अपवाद आईडी की पहुंच है, जो प्रॉक्सी में पहले से ही उपलब्ध है)।

तो आप अपने तरीकों को सुरक्षित रूप से कार्यान्वित कर सकते हैं जैसे प्रॉक्सी नहीं थे - व्यापार-बंद के साथ विधि को आभासी होने की आवश्यकता है (जो - मैं सहमत हूं - सही नहीं है)।

यदि आपको लगता है कि यह आपके क्लास डिज़ाइन के लिए एक समस्या है, तो कार्यक्षमता को किसी अन्य वर्ग (जैसे पासवर्ड मैनेजर, पासवर्ड वैलिडेटेटर आदि) में स्थानांतरित करने का प्रयास करें। यह वर्ग खाता एकत्र करेगा या इसे तर्क के रूप में ले जाएगा, इसलिए खाता केवल तभी लोड किया जाएगा जब यह वर्ग वास्तव में अपनी संपत्तियों में से एक को कॉल करे।

+0

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

+0

@ पॉल: नहीं, आप गलत समझते हैं। आप * अपने तरीकों से फ़ील्ड * सीधे * एक्सेस कर सकते हैं। इसमें कुछ भी गलत नहीं है, आपको इस मामले में आलसी लोडिंग के बारे में चिंता करने की आवश्यकता नहीं है। आपकी इकाइयों में कोड * पूरी तरह से प्रारंभिक इकाई के भीतर हमेशा * निष्पादित होता है। यह एनएच को अधिक पारदर्शी बनाता है। उदाहरण के लिए यह वास्तव में दुर्लभ है कि उदाहरण के राज्य पर निर्भर नहीं है, इसलिए ऑप्टिमाइज़ करने के लिए बहुत सीमित स्थान है। –

+0

आह, मैंने गलत समझा। क्षेत्र की पहुंच की सुरक्षा करना समझ में आता है। –

0

मैंने देखा है कि एनएचबीर्नेट अपने सभी इकाइयों के लिए पीओसीओ पर भारी निर्भर करता है। बेहतर या बदतर के लिए, मैंने किसी भी परिदृश्य में भाग नहीं लिया है जहां किसी ने उस सम्मेलन को तोड़ दिया है। डेवी ब्रायन explains it in great detail here.(वह अपनी बात है कि, हाँ, आप आलसी नहीं भार के रूप में कक्षाएं चिह्नित कर सकते हैं संदर्भ देता है। लेकिन, के बाद से nHibernate फिर अपने प्रॉक्सी के किसी भी उत्पन्न नहीं करेगा, आप अटक कर रहे हैं।)

मैं डॉन ' टी यह नहीं जानता कि यह सहायक है, लेकिन कैसल कैसा करता है। अब जब (यदि आप 2.1 का उपयोग कर रहे हैं) you're able to choose which proxy generator to use, one of the other choices पर जाने से आप अपनी जरूरतों के अनुरूप प्रॉक्सी उत्पन्न कर सकते हैं।

0

आप कक्षा स्तर पर आलसी लोडिंग को निष्क्रिय कर सकते हैं और इसे संपत्ति के आधार पर संपत्ति पर सक्रिय कर सकते हैं, आलसी लोडिंग अक्सर संग्रह-मूल्यांकन संबंधों के लिए उपयोग की जाती है।

public class AccountMap : ClassMap<Account>{   
    public AccountMap() 
    { 
     Not.LazyLoad(); 
     Id(x => x.Id); 
     Map(x => x.Username).LazyLoad(); 
     Map(x => x.Password);   
    } 
} 

या आप के लिए एक निजी क्षेत्र और इसके लिए एक "मैदान" रणनीति के साथ की कोशिश कर सकते हैं:

public class AccountMap : ClassMap<Account>{   
    public AccountMap() 
    { 

     Id(x => x.Id); 
     Map(x => x.Username) 
     Map(x => x.Password).Access.AsCamelCaseField();   
    } 
} 

public class AccountMap : ClassMap<Account>{   
    private string password; 
    public string Password{ get; } 
} 
+0

क्या मानचित्र के समान कुछ है (x => x.Method()) .Not.LazyLoad()? –

+0

आप इस प्रॉपर्टी के साथ प्रॉक्सी पीढ़ी केकेक को भी निष्क्रिय कर सकते हैं: use_proxy_validator को झूठी – MatthieuGD