7

मेरे एएसपी.नेट एमवीसी अनुप्रयोग में मैंने डोमेन मॉडल को मॉडल मॉडल से अलग कर दिया है।
मैं अपनी इकाई को व्यूमोडेल ऑब्जेक्ट में बदलता हूं ताकि मैं अपने विचारों को केवल आवश्यक डेटा के साथ "फ़ीड" कर सकूं (मैंने इस उद्देश्य के लिए वैल्यूजेक्टर का उपयोग किया था)।
सहेजने की प्रक्रिया के दौरान मेरा नियंत्रक व्यूमोडेल ऑब्जेक्ट को वापस ले जाता है, इसे डोमेन मॉडल इकाई में बदल देता है और इसे SaveOrUpdate के साथ जारी रखने का प्रयास करता है। मैंने देखा है कि यदि मैं मौजूदा रिकॉर्ड को अपडेट करने का प्रयास करता हूं, तो निबर्ननेट इसे एक नई वस्तु के रूप में मानता है और एक आईएनएसईआरटी को मजबूर करता है, भले ही मेरी इकाई के पास उचित आईडी हो।
मैंने इकाई को लोड नहीं किया है (कारण/लोड करें) क्योंकि मैं फिर से सभी क्षेत्रों को दोबारा मैप करना चाहता हूं।
क्या कुछ भी गलत है? इसे प्राप्त करने का सबसे अच्छा तरीका क्या है?क्या मुझे Nhibernate में SaveOrUpdate से पहले एक इकाई लोड/प्राप्त करना है?

***** - अद्यतन - ***

मेरे नियंत्रक एक उपयोगकर्ता (ViewModel) प्राप्त करता है, यह पुष्टि करता है और एक इकाई के रूप में एक सेवा परत के माध्यम से इसे सहेजने के लिए कोशिश करता है:

public ActionResult Edit(Guid id, Models.User User) 
{ 
... 
var user = new Domain.User(); 
user.InjectFrom(User); 
user.SetId(id); 

user = this._SecurityService.SaveUser(user); 

} 

public Domain.User SaveUser(Domain.User User) 
     { 
      bool Result = false; 

      if (this._ValidationEngine.IsValid(User)) 
      { 
       using (_UnitOfWork) 
       { 
        if (User.Code != Guid.Empty) 
        { 
         var user = this._UserRepository.Load(User.Code); 
         user.InjectFrom(User); 
         User = this._UserRepository.Update(user); 
        } 
        else { 
         User = this._UserRepository.Save(User); 
        } 
        Result = _UnitOfWork.Commit(); 
       } 
      } 
      return (User); 
     } 

मैं इस तथ्य मैं अपने viewmodel/संस्था कई बार बदलने के लिए है के बारे में एक चिंता का विषय मिल गया है: यह सेवा है। अब जब मैं एक नया उपयोगकर्ता सहेजने की कोशिश करता हूं तो मुझे यह संदेश मिला: पंक्ति को किसी अन्य लेनदेन द्वारा अपडेट या हटा दिया गया था (या सहेजे गए-मूल्य मैपिंग गलत था)
शायद यह डारिन मुझे क्या बता रहा था उससे संबंधित कुछ तरीकों से है।
क्या मैं ऐसा करने का प्रयास करने के बेहतर तरीके हैं?

अद्यतन

मैंने देखा है कि त्रुटि "पंक्ति अद्यतन या नष्ट कर दिया गया था ..." तथ्य मैं एक संस्करण मेरी मैपिंग के लिए परिभाषित किया गया है कि कारण होता है। मैं समझ सकता हूं कि मुझे आईडी और संस्करण उस इकाई से मेल खाने की आवश्यकता है जिसे मैं अपडेट करना चाहता हूं।
मैं समझना चाहता हूं कि अन्य लोग डीडीडी + एएसपी.नेट एमवीसी + एनएचबीरनेट के साथ इन चीजों को कैसे करते हैं ???

समाधान

मेरे सभी संस्थाओं एक संस्करण को परिभाषित किया है (मैं कहना है, खेद भूल गया):

<version name="Version" type="System.Int32" unsaved-value="0"> 
    <column name="Version" not-null="true" /> 
</version> 

रूप Ayende समझाया here, Nhibernate इस तरह एक प्रश्न के साथ मेरी इकाई को अपडेट करने की कोशिश करता है :

UPDATE Table SET field1 = 'bla', Version = (y+1) WHERE id = x AND Version = y 

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

User = this._UserRepository.Update(user); 

इसका मतलब है कि अगर मैं एक StaleObjectException अपवाद है कि किसी डीबी पंक्ति को अपडेट किया गया और मैं उपयोगकर्ता को कुछ प्रतिक्रिया के साथ प्रदान करूंगा।

+0

इकाई को लोड करने का प्रयास करें और इसे फिर से मैप करने के बाद (मुझे पता है कि आप इसे इस तरह से नहीं चाहते हैं), बस इसे आज़माएं और हमें बताएं कि यह इस तरह से काम करता है – Omu

+0

मुझे लगता है कि मेरी समस्या संस्करण के साथ है। मैंने <कॉलम नाम =" संस्करण "नॉन-नल =" सत्य "/> मेरे मैपिंग में परिभाषित किया गया। मुझे लगता है कि मेरे पास है ऐसा करने के लिए एक बेहतर तरीका खोजने के लिए। – LeftyX

उत्तर

0

चूंकि आपके पास पहले से ही एक आईडी है और इसलिए, यह पता है कि यह एक अद्यतन है, SaveOrUpdate के बजाय session.Update का उपयोग करें।

+0

मुझे डर है कि अगर मैं अपनी इकाई को बचाने की कोशिश करता हूं तो मैं ऐसा नहीं कर सकता हूं, मुझे यह संदेश मिलता है: एक ही पहचानकर्ता मान के साथ एक अलग वस्तु पहले से ही सत्र से जुड़ी हुई थी: caedb8a4-abce-4c6f-b171-9e7200cc7a37, इकाई का : BpReminders.Domain.User – LeftyX

+0

इसका मतलब है कि ऑब्जेक्ट पहले ही लोड हो चुका है। आप पहले से लोड किए गए ऑब्जेक्ट को अपडेट क्यों नहीं कर रहे हैं? –

+0

खेद है कि एक गलती थी। अब मैं जो कर रहा हूं वह एक इकाई को भंडार से लोड कर रहा है और इसे नियंत्रक से प्राप्त एक के साथ विलय कर रहा है। मुझे अभी भी एक त्रुटि मिलती है "पंक्ति को किसी अन्य लेनदेन द्वारा अपडेट या हटा दिया गया था (या सहेजे गए-मूल्य मैपिंग गलत था)" जब मैं सम्मिलित करने का प्रयास करता हूं। मैं अपने मूल प्रश्न को अधिक जानकारी के साथ अपडेट करूंगा। – LeftyX

4

SaveOrUpdate के लिए काम करने के लिए उम्मीद है कि आपको अपने <id> मैपिंग पर unsaved-value विशेषता स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता है। उदाहरण के लिए आप होगा:

<id unsaved-value="0" ... 

और फिर एक मॉडल है जो ईद संपत्ति एक मूल्य 0 से अलग करने के लिए सौंपा गया है पर एक SaveOrUpdate कॉल जारी करने और यह UPDATE बजाय INSERT जा रहा है। तो अपने प्रश्न का उत्तर देने के लिए, नहीं, आपको UPDATE से पहले SELECT मैन्युअल रूप से जारी करने की आवश्यकता नहीं है। SaveOrUpdate इसे दृश्यों के पीछे करना चाहिए।

+0

धन्यवाद साहसी। मुझे लगता है कि मुझे एक खाली ग्रिड (00000000-0000-0000-0000-0000-000000000000) का उपयोग करना है यदि मेरी आईडी टाइप है, तो सही है? – LeftyX

+0

@vandalo, इसे आज़माएं: 'unsaved-value =" 00000000-0000-0000-0000-000000000000 "' (अवांछित)। –

+0

धन्यवाद, फिर से। आप क्या करेंगे, वैसे भी? क्या मुझे डीबी से इकाई को लोड करना चाहिए और प्रत्येक फ़ील्ड को नई इकाई के साथ पॉप्युलेट करना चाहिए सीए में मैं अद्यतन करने की कोशिश कर रहा हूँ? क्या कोई सर्वोत्तम अभ्यास है? आपकी सहायता के लिए एक बार फिर से धन्यवाद। – LeftyX

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^