2011-06-07 11 views
5

मेरे पास क्लास व्यक्ति एनएचबीर्नेट के साथ डेटाबेस में मैप किया गया है। मैं डीबी से वस्तुओं को लोड करता हूं और इसे विभिन्न ग्राहकों को भेजता हूं। पहला ग्राहक नाम और देश की संपत्ति को संशोधित करेगा। दूसरा ग्राहक केवल नाम संपत्ति को संशोधित करेगा। फिर दोनों सर्वर पर संशोधित ऑब्जेक्ट लौटाते हैं। जब मैं पहले क्लाइंट से डेटा सहेजता हूं - तब सही ढंग से सहेजा जाता है, दोनों नाम और देश अपडेट किए जाते हैं। जब मैं दूसरे क्लाइंट से डेटा सहेजता हूं - मुझे समस्या है। यह पहले ग्राहक से डेटा ओवरराइड था और देश का नया नाम और प्रारंभिक मूल्य बचाता था।मैं केवल परिवर्तित गुणों को सहेजने के लिए NHibernate को कैसे बता सकता हूं

मैं एनएचबेर्नेट को केवल नाम मान बचाने के लिए कैसे बता सकता हूं और देश मूल्य को ओवरराइड नहीं कर सकता?

public class Person 
{ 
    public string Name { get; set; } 
    public string Country { get; set; } 
} 

public static List<Person> GetEntities() 
{ 
    var factory = CreateSessionFactory(); 
    using (ISession session = factory.OpenSession()) 
    { 
     return session.CreateCriteria<Person>().List<Person>();     
    } 
} 

public static void SaveEntities(List<Person> entities) 
{ 
    var factory = CreateSessionFactory(); 
    using (ISession session = factory.OpenSession()) 
    { 
     using (var t = session.BeginTransaction()) 
     { 
      foreach (var person in entities) 
      { 
       session.Merge(person); 
      } 

      t.Commit(); 
     } 
    } 
} 

पी.एस: के लिए खेद है मेरा बुरा अंग्रेजी

उत्तर

1

उत्तर है: आप नहीं कर सकते। एनएच नहीं जानता कि केवल नाम बदल गया है।

समवर्ती संपादन की अनुमति न देकर आप इससे बच सकते हैं। उदाहरण के लिए एनएच के आशावादी लॉकिंग तंत्र द्वारा। दूसरे ग्राहक को StaleObjectStateException मिलेगा।

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

यदि आप समवर्ती संपादन रखना चाहते हैं, तो आपके पास कुछ काम करने के लिए बहुत कुछ है। ग्राहक को वास्तव में जो जानकारी बदल गई थी, वह जानकारी प्रदान करने की आवश्यकता है। फिर आपको केवल इन मानों की प्रतिलिपि बनाना होगा। यह कड़ी मेहनत है। फिर आपको अभी भी समस्या हो सकती है कि विलय किए गए मान फिट नहीं होते हैं।

+0

धन्यवाद स्टीफन।मैं ऑब्जेक्ट में परिवर्तनों का पता लगाने के लिए ऑब्जेक्ट के दूसरे क्लाइंट मूल स्थिति से वापस भेज सकता हूं और केवल संशोधित गुणों को सहेज सकता हूं। – gagabu

+1

यह ध्यान रखना महत्वपूर्ण है कि यह उत्तर केवल प्रश्न के संदर्भ में सच है, जहां ओपी अलग-अलग इकाइयों के साथ काम करता है। यदि कोई मौजूदा सत्र से लोड की गई संस्थाओं के साथ काम करता है, तो एनएचबीर्नेट केवल उन्हीं गुणों को अपडेट कर सकता है, उन इकाइयों को उनकी 'कक्षा' घोषणा पर सक्षम 'गतिशील-अपडेट' के साथ मैप करके, [विद्रोहकर्ता द्वारा उत्तर दिया गया] (/ a/6271210/1178314) । –

2

यह एक संगामिति समस्या है। दूसरा क्लाइंट यह नहीं जानता कि डेटा इसे पढ़ने के बाद बदल गया है, इसलिए उनके परिवर्तन पहले क्लाइंट के परिवर्तनों को ओवरराइट करते हैं। इसे एनएचबर्ननेट में several methods में से एक द्वारा संभाला जा सकता है, जिसमें से सबसे आम संस्करण कॉलम का उपयोग करना है।

यह समस्या निवारण आसान है, बड़ी समस्या उपयोगकर्ता के होने पर अच्छी प्रतिक्रिया प्रदान कर रही है।

+0

मैं पूरी तरह से इस अंक के साथ सहमत हैं ... लेकिन इस सवाल का नहीं था। प्रश्न यह था कि केवल नाम को कैसे बचाया जाए। –

0

के रूप में जेमी इदे सही ढंग से कहा, क्या आप अनुभव कर रहे संगामिति समस्या, नहीं एक मानचित्रण समस्या है ..

जब आप अपने वस्तु की अपनी nhibernate मानचित्रण नहीं बना, जो कुछ भी डेटा वर्तमान में उन वस्तुओं हो जाएगा सत्र फ़्लश होने के बाद डेटाबेस में सहेजा गया (या अपडेट किया गया)। आप अलग-अलग फ़ील्ड को अपडेट करने के लिए नामित नहीं कर सकते हैं, यह सब कुछ या कुछ भी नहीं है।

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

12

असल में, आप एनएचबर्ननेट को Dynamic Update का उपयोग करके "गंदे" फ़ील्ड को विशेष रूप से अपडेट करने के लिए कह सकते हैं।

अधिक पर: http://ayende.com/blog/3946/nhibernate-mapping-concurrency

+1

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

+0

मैंने पोस्ट प्रश्न से पहले इस लेख को पढ़ा। लेकिन मुझे अपनी समस्या का उत्तर नहीं मिल रहा है: दूसरे क्लाइंट से केवल नाम को कैसे सहेजना है। – gagabu

+0

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