2014-02-14 75 views
0

我有一個線程可以查找數據庫中最新的記錄並使用它們進行操作(使用ODBC)。從線程獲取數據庫中的最新記錄

我遇到的問題是,當我在線程運行時手動插入兩條記錄到我的數據庫時,它返回兩條記錄,然後只是最後一條記錄。

我怎樣才能讓它返回這2條記錄?

這裏是我的代碼:

public void Run() 
{ 
    // thread alive is set to true, in the main program it is set to false when the user quits 
    while (RestTestThread.ThreadAlive) 
    { 
     System.Threading.Thread.Sleep(1000); // set to 1000 for quick testing 
     try 
     { 
      // get the data from the database and return to a List<string> 
      List<string> postList = Controllers.OdbcController.GetRecords(); 

      // convert that list into a string 
      string post = string.Join(",", postList.ToArray()); 

      // format that data 
      string postData = "{\"Data\":[" + post.TrimEnd(new char[] { ',' }) + "]}"; 
      Program.postString.Clear(); 

      // test output 
      Console.WriteLine(postData); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
      break; 
     } 
    } 
} 

這是Controllers.OdbcController.GetRecords()方法:

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Data.Odbc; 
using System.Linq; 
using System.Text; 

namespace WatchItRDBMSService.Controllers 
{ 
    public class OdbcController 
    { 
     private static string _lastId; 
     private static string _dsn; 
     private static string _postData; 
     private static OdbcConnection _connection; 
     private static OdbcCommand _command; 
     private static OdbcDataReader _reader; 

     public static List<string> GetRecords() 
     { 
      List<string> result = new List<string>(); 
      _dsn = ConfigurationManager.AppSettings["OdbcDsn"]; 

      if (_dsn != "") 
      { 
       if (ConfigurationManager.AppSettings["LastId"] == "") 
       { 
        // first read, initial, first run of the thread 
      // create connection settings 
        string qry = String.Format("SELECT ID, TestValue FROM test.new_table"); 
        _connection = new OdbcConnection(_dsn); 
        _connection.Open(); 
        _command = _connection.CreateCommand(); 
        _command.CommandText = qry; 
        _reader = _command.ExecuteReader(); 

        while (_reader.Read()) 
        { 
         _postData = String.Empty; 
         _postData += "{"; 

         // rows exist (1 or more) 
         for (int i = 0; i < _reader.FieldCount; i++) 
         { 
          if (_postData.Length == 1) 
          { 
           _postData += String.Format("\"{0}\":\"{1}\"", _reader.GetName(i), _reader.GetValue(i)); 
          } 
          else 
          { 
           _postData += String.Format(",\"{0}\":\"{1}\"", _reader.GetName(i), _reader.GetValue(i)); 
          } 
         } 
         _postData += "}"; 

         result.Add(_postData); 

      // update the latest ID in App.config 
         _lastId = _reader.GetValue(0).ToString(); 
         Common.UpdateConfigFile.UpdateAppSetting("LastId", _lastId); 
        } 

        _reader.Close(); 
        _command.Dispose(); 
        _connection.Close(); 
       } 
       else 
       { 
        // successive reads, additions to table will be discovered here 
      // set up database connections 
        string qry = String.Format("SELECT ID, TestValue FROM test.new_table WHERE ID > {0} ORDER BY ID DESC", Convert.ToInt32(ConfigurationManager.AppSettings["LastId"])); 
        _connection = new OdbcConnection(_dsn); 
        _connection.Open(); 
        _command = _connection.CreateCommand(); 
        _command.CommandText = qry; 
        _reader = _command.ExecuteReader(); 

        while (_reader.Read()) 
        { 
         _postData = String.Empty; 
         _postData += "{"; 

         // rows exist (1 or more) 
         for (int i = 0; i < _reader.FieldCount; i++) 
         { 
          if (_postData.Length == 1) 
          { 
           _postData += String.Format("\"{0}\":\"{1}\"", _reader.GetName(i), _reader.GetValue(i)); 
          } 
          else 
          { 
           _postData += String.Format(",\"{0}\":\"{1}\"", _reader.GetName(i), _reader.GetValue(i)); 
          } 
         } 
         _postData += "}"; 

         result.Add(_postData); 

       // update the latest ID in App.config 
         _lastId = _reader.GetValue(0).ToString(); 
         Common.UpdateConfigFile.UpdateAppSetting("LastId", _lastId); 
        } 

        _reader.Close(); 
        _command.Dispose(); 
        _connection.Close(); 
       } 
      } 
      else 
      { 
       Console.WriteLine("No Database Connection(s) exist."); 
      } 
      return result; 
     } 
    } 
} 

我的測試表已ID & TestValueID是自動增量)

例如,當我插入2個值時,請說:ID=17 TestValue="Test1", ID=18 TestValue="Test2"

我得到這個:

{"Data": [{"ID":18, "TestValue":"Test2"}, {"ID":17, "TestValue":"Test1"}]} 
{"Data": [{"ID":18, "TestValue":"Test2"}]} 

但我只是想:

{"Data": [{"ID":18, "TestValue":"Test2"}, {"ID":17, "TestValue":"Test1"}]} 
+0

我編輯了自己的冠軍。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

+0

好的,謝謝。我忘了那個抱歉。 – user

+0

什麼是Controllers.OdbcController.GetRecords();做? – automatic

回答

1

如果我是你,我會保留上次讀取id從數據集。

因此,您需要將您的Controllers.OdbcController.GetRecords()更改爲接受id並返回最新的一個。

GetRecords檢查id使用where子句。

編輯:

根據您的更新:你確定的ID被傳遞給正確的配置?

您使用兩個不同的調用來保存和檢索:

ConfigurationManager.AppSettings["LastId"] 

Common.UpdateConfigFile.UpdateAppSetting("LastId", _lastId) 

爲什麼不能用呢?

ConfigurationManager.AppSettings["LastId"] = _lastId; 
+0

在我的GetRecords()方法中,我已經有了一個where子句,並且我從app.config文件獲取ID。執行查詢時,該方法也將該ID保存在app.config文件中。我用GetRecords()方法編輯了我的問題。 – user

+0

@user:請參閱更新 –

+0

UpdateAppSetting執行此操作:public static void UpdateAppSetting(string key,string value) { Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings.Remove(key); config.AppSettings.Settings.Add(key,value); config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection(「appSettings」); }'我測試了一下,看它是否更新了ID,它確實是 – user

0

它更好地使用C#鎖定對象。鎖對象可防止只有一個線程訪問關鍵區域。

private object lockObj=new object(); 

public void Run() 
{ 
// thread alive is set to true, in the main program it is set to false when the user quits 
while (RestTestThread.ThreadAlive) 
{ 
    System.Threading.Thread.Sleep(1000); // set to 1000 for quick testing 
    try 
    { 
     lock(lockObj) 
     { 
      // get the data from the database and return to a List<string> 
      List<string> postList = Controllers.OdbcController.GetRecords(); 

      // convert that list into a string 
      string post = string.Join(",", postList.ToArray()); 

      // format that data 
      string postData = "{\"Data\":[" + post.TrimEnd(new char[] { ',' }) + "]}"; 
      Program.postString.Clear(); 

      // test output 
      Console.WriteLine(postData); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
     break; 
    } 
} 

}

+0

因爲這只是一個'while'循環,所以沒有什麼可以鎖定的。 –

+0

這仍然返回我描述的那兩行。 – user

相關問題