2011-07-05 12 views
8

मुझे एनएचबर्ननेट के साथ काम करते समय एक TooManyRowsAffectedException मिला है और मैंने TooManyRowsAffectedException with encrypted triggers जैसे विभिन्न बैचर इंजेक्शन करके या SET NOCOUNT चालू करने के लिए डेटाबेस में ट्रिगर्स को संशोधित करके (इसके बाद से इसका उपयोग नहीं कर सकता) मैं डेटाबेस को संशोधित नहीं करना चाहता - यह एक साथ सौ से अधिक तालिकाओं के साथ बहुत जटिल है और मैं इसके साथ गड़बड़ नहीं करना चाहता क्योंकि अन्य अनुप्रयोग इसका उपयोग करते हैं)। मुझे समझ में नहीं आता कि यह अपवाद क्यों होता है। मैं बस इतना करता हूं कि मेरे पास एक नमूना वस्तु है जिसे मैंने दो मानों को देखा है, और यदि मान दिए गए मानदंडों के साथ फिट होते हैं, तो मैंने नमूना सेट किया है। 'पंक्ति' को 'Y' में चलाया गया है (हमारे डेटाबेस में सभी बूलियन का प्रतिनिधित्व किया जाता है चार वाई या एन)। कोड बहुत आसान है:NHibernate को कैसे बताना है कि एक ट्रिगर दूसरी तालिका अपडेट करता है?

IQueryable<Sample> samples = session.Query<Sample>().Where(s =­­> s.Value == desiredValue); 
foreach (Sample sample in samples) 
{ 
    sample.IsDone = 'Y'; 
    session.Flush(); // Throws TooManyRowsAffectedException 
} 
session.Flush(); // Throws TooManyRowsAffectedException 

फ़्लश कॉल फेंकता है कि क्या मैं इसे लूप के अंदर या बाहर रखता हूं। क्या कुछ ऐसा है जो मैं गलत कर रहा हूं या क्या यह केवल डेटाबेस के तरीके से संबंधित है? मैंने Flush() से पहले नमूना पर SaveOrUpdate() को कॉल करने का प्रयास किया, लेकिन यह कुछ भी नहीं बदला। मुझे पता है कि मैं इस अपवाद के आसपास काम कर सकता हूं, लेकिन मैं समस्या के स्रोत को समझना पसंद करूंगा।

नोट: अपवाद में यह मुझे बताता है कि वास्तविक पंक्ति गणना 2 है और अपेक्षित 1 है। यह 2 पंक्तियों को क्यों अपडेट करता है क्योंकि मैं केवल 1 पंक्ति बदलता हूं?

आपकी मदद के लिए धन्यवाद!

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

मैं पता लगाने के लिए कि उस का कारण कंटेनर तालिका (कंटेनर नमूने होते हैं) जब नमूना अद्यतन किया जाता है में एक पंक्ति को अद्यतन करने के डेटाबेस में एक ट्रिगर है क्योंकि वहाँ है कर रहा था। क्या NHibernate को कॉन्फ़िगर करने का कोई तरीका है ताकि यह इस ट्रिगर के बारे में जानता हो और उम्मीद की जा सके कि पंक्तियों की सही संख्या अपडेट हो जाए?

उत्तर

5

मैं चारों ओर केवल काम मिल गया है धाराप्रवाह NHibernate का उपयोग कर नीचे कोड स्निपेट में दिखाया गया है। यह बदसूरत है क्योंकि यह आपके मैपिंग में एसक्यूएल कोडिंग कठिन है लेकिन यह काम करता है। चेक प्रॉपर्टी को किसी को भी सेट नहीं किया गया है ताकि गणना को अनदेखा किया जा सके। मुझे नहीं पता कि क्या आप इसे सीधे एचबीएम फाइलों का उपयोग करके पूरा कर सकते हैं लेकिन शायद एक तरीका है। यह बहुत अच्छा होगा कि NHibernate (या Fluent NH) में कॉन्फ़िगरेशन विकल्प था या तो अपेक्षित अद्यतन पंक्ति गणना सेट करें या आवश्यकता होने पर इसे अनदेखा करें।

public class OrderMap : ClassMap<Order> 
{ 
    public OrderMap() 
    { 
     Id(c => c.Id, "order_id").GeneratedBy.Native(); 

     Table("order"); 

     Map(c => c.GroupId, "group_id"); 
     Map(c => c.Status, "status"); 
     Map(c => c.LocationNumber, "location"); 

     SqlInsert("insert into order (group_id, status, location) values (?, ?, ?)").Check.None(); 
     SqlUpdate("update order set group_id = ?, status = ?, location = ? where order_id = ?")).Check.None(); 
     SqlDelete("delete order where order_id = ?").Check.None(); 
    } 
} 

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

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="Your.DomainModel.Entities.Order, Your.DomainModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="order"> 
    <id name="Id" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" unsaved-value="0"> 
     <column name="order_id" /> 
     <generator class="identity" /> 
    </id> 
    <property name="GroupId" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="group_id" /> 
    </property> 
    <property name="Status" type="System.Int16, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="status" /> 
    </property> 
    <property name="LocationNumber" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="loc_num" /> 
    </property> 
    <sql-insert check="none">insert into order (group_id, status, location) values (?, ?, ?)</sql-insert> 
    <sql-update check="none">update order set group_id = ?, status = ?, location = ? where order_id = ?</sql-update> 
    <sql-delete check="none">delete order where order_id = ?</sql-delete> 
    </class> 
</hibernate-mapping> 
+0

मैं फ्लुएंट एनएचबेर्नेट का उपयोग नहीं कर रहा हूं, क्या आप जानते हैं कि यह NHibernate सेटिंग्स में कहां लागू होता है? मैं यह नहीं समझ सकता कि मुझे कहां लिखना चाहिए (मैं किसी भी क्लासमैप का उपयोग नहीं करता हूं, न ही मुझे पता है कि यह क्या है, और मैंने एसक्लइन्सर्ट या जैसे कार्यों को नहीं देखा है)। – Carl

+0

कृपया मेरे उत्तर में संपादन देखें। उम्मीद है कि आप हाथ से एचबीएम नहीं बना रहे हैं। लेकिन यदि हैं, तो निश्चित रूप से देखें कि Fluent NHibernate या NHibernate 3.0 में नई धाराप्रवाह मैपिंग क्षमता आपके लिए क्या कर सकती है। –

+1

इसके लिए धन्यवाद। हां, मैं हाथ से एचबीएम बना रहा हूं लेकिन अब यह कोई समस्या नहीं है (मुझे नहीं लगता कि यह विशेष रूप से कठिन है)। – Carl

2

निष्पादित होने वाले एसक्यूएल के प्रोफाइलर से जांचें। anjlab sql profiler हमेशा मेरे लिए चाल है।

यह जांचने के बाद कि क्या उस तालिका में ट्रिगर्स हैं - शायद वे कुछ परेशानी पैदा कर रहे हैं।

संपादित

आप यहाँ की तरह अपने ट्रिगर बदल चाहिए: http://www.codewrecks.com/blog/index.php/2009/03/25/nhibernate-and-toomanyrowsaffectedexception/

+0

लिंक के लिए धन्यवाद।आप सही थे मैंने देखा कि एक नमूना अद्यतन होने पर कंटेनर के अंतिम_अपडेटेड_डेट कॉलम (जिसमें नमूने होते हैं) को अद्यतन करने वाला एक ट्रिगर होता है। क्या आपको पता है कि एनएचबीर्नेट को यह उम्मीद करने का कोई तरीका है या नहीं? – Carl

+0

मुझे लगता है कि ऐसा होने जा रहा है, क्योंकि मुझे इसे काम करने का कोई और तरीका नहीं मिला है, लेकिन 10+ विभिन्न अनुप्रयोगों के साथ डेटाबेस का उपयोग कर 100+ क्लाइंट हैं, इसलिए मुझे नहीं पता कि ट्रिगर को संशोधित करने में क्या हो सकता है किसी अन्य एप्लिकेशन में कुछ काम करना बंद करो। – Carl

1

वहाँ: उन दुर्भाग्यपूर्ण लोगों कि धाराप्रवाह NHibernate की जानकारी नहीं है या हाथ से HBM फ़ाइलों की दर्दनाक पीढ़ी प्यार के लिए, यहाँ यह नमूना मानचित्रण के लिए HBM फ़ाइल है एनएचबीर्नेट को यह बताने के लिए आप कुछ भी नहीं कर सकते हैं कि ट्रिगर ने डेटाबेस में दूसरी इकाई को अपडेट किया है, सिवाय इसके कि सिक्सटो सैज़ अपने जवाब में दिखाता है। हालांकि आप कोड में ट्रिगर कार्रवाई करने के लिए EventListeners का उपयोग कर सकते हैं। या ट्रिगर की शुरुआत में SET NOCOUNT सेट करें और अंत में एक सेट NOCOUNT बंद करें यदि अपडेट आपके शेष लेनदेन के लिए कोई फर्क नहीं पड़ता है।

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