2010-03-05 10 views
5

के साथ संघर्ष करता है हम अपने अनुप्रयोग में माइक्रोसॉफ्ट सिंक फ्रेमवर्क को लागू करने की कोशिश कर रहे हैं जो NHBernate का उपयोग कर अपने डोमेन को जारी रखता है।माइक्रोसॉफ्ट सिंक फ्रेमवर्क Nhibernate TooManyRowsAffectedexception

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

मुझे यह आलेख मिला है जिसमें प्रत्येक अद्यतन कथन के आस-पास सेट और बंद करने का समाधान है, लेकिन चूंकि तालिका संरचना स्वचालित रूप से निबर्ननेट द्वारा उत्पन्न होती है और सिंक ट्रिगर स्वचालित रूप से सिंक फ्रेमवर्क द्वारा जेनरेट किए जाते हैं, सभी ट्रिगर्स को मैन्युअल रूप से समायोजित करते हैं वास्तव में एक विकल्प नहीं है।

http://www.codewrecks.com/blog/index.php/2009/03/25/nhibernate-and-toomanyrowsaffectedexception/

मैं इस सवाल में वर्णित के रूप में एसक्यूएल सर्वर 2008 संपत्ति NOCOUNT स्थापित करने की कोशिश की: Where's the best place to SET NOCOUNT? लेकिन यह एक StaleStateException में हुई (-1 पंक्तियों प्रभावित, 1 की उम्मीद है)।

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

अग्रिम में Thx!

उत्तर

6

मुझे लगता है कि एनओसीएटी रास्ता जाने का रास्ता है। आप सिंक फ्रेमवर्क द्वारा उपयोग की जाने वाली सभी तालिकाओं के लिए NOCOUNT सेट करके ऐसा कर सकते हैं। नीचे दिया गया कोड देखें। एक और तरीका है NHibernate को पैच करना और अपडेटकाउंट को अनदेखा करना (https://nhibernate.jira.com/browse/NH-1353)।

के.आर.,

पॉल

class SqlSyncTriggerHelper 
{ 
    private const string triggerSql = @"select sys.triggers.name from sys.triggers, sys.objects 
     where sys.objects.name='{0}' and sys.objects.type = 'U' and sys.triggers.parent_id = sys.objects.object_id"; 

    private DbSyncScopeDescription syncScopeDescription; 

    public SqlSyncTriggerHelper(DbSyncScopeDescription syncScopeDescription) 
    { 
     this.syncScopeDescription = syncScopeDescription; 
    } 

    public void Apply(SqlConnection conn) 
    { 
     SqlTransaction transaction = null; 
     try 
     { 
      if (conn.State == System.Data.ConnectionState.Closed) 
      { 
       conn.Open(); 
      } 
      transaction = conn.BeginTransaction(); 
      foreach (var table in syncScopeDescription.Tables) 
      { 
       foreach (string trigger in GetTriggers(table.UnquotedLocalName, conn, transaction)) 
       { 
        AlterTrigger(trigger, conn, transaction); 
       } 
      } 
      transaction.Commit(); 
     } 
     catch 
     { 
      if (transaction != null) 
      { 
       transaction.Rollback(); 
      } 
      throw; 
     } 
     finally 
     { 
      if (transaction != null) 
      { 
       transaction.Dispose(); 
      } 
      conn.Close(); 
     } 
    } 

    private void AlterTrigger(string trigger, SqlConnection conn, SqlTransaction transaction) 
    { 
     SqlCommand newCmd = new SqlCommand(string.Format("exec sp_helptext '{0}'", trigger), conn, transaction); 
     var triggerStringBuilder = new StringBuilder(); 
     using (var reader = newCmd.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       triggerStringBuilder.Append(reader.GetValue(0) as string); 
      } 
     } 
     var triggerString = triggerStringBuilder.ToString(); 
     triggerString = triggerString.Replace("CREATE TRIGGER", "ALTER TRIGGER").Replace(" AS\n", " AS\nSET NOCOUNT ON\n") + "\nSET NOCOUNT OFF"; 
     var alterTriggerCommand = new SqlCommand(triggerString, conn, transaction); 
     alterTriggerCommand.ExecuteNonQuery(); 
    } 

    private IEnumerable<string> GetTriggers(string tableName, SqlConnection conn, SqlTransaction transaction) 
    { 
     var resultList = new List<string>(); 
     var command = new SqlCommand(string.Format(triggerSql, tableName), conn, transaction); 
     using (var reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       resultList.Add(reader.GetString(0)); 
      } 
     } 
     return resultList; 
    } 
} 
संबंधित मुद्दे