2012-04-12 65 views
0

我正在使用Visual C#Studio 2010 express,並試圖批量更新我的表。每當我嘗試更新1條記錄時,我都會收到「併發衝突:UpdateCommand影響了預期的1條記錄中的0條。」我在代碼的夢中問了這個問題,但是我對一些誠實問題的迴應有些失望。 Link to my question at D.I.C如何使用TableAdapter更新DatabaseDataSet?

我採取了最後的建議,並改變了我的代碼來影響數據集..或者我認爲,但我仍然得到併發問題。這是我更新的代碼。

 private void SendNewPotentialsToZoho() 
    { 
     Console.WriteLine("Trying to send potentials to Zoho"); 

     var newZoho = potentialDatabaseDataSet.Potential.DefaultView; 
     var poster = new ZohoPoster(ZohoPoster.Fields.Potentials, ZohoPoster.Calls.insertRecords); 
     var count = 0; 

     //newZoho.RowFilter = "IsNull(ZohoID,'zoho') = 'zoho'"; 
     newZoho.RowFilter = "Soid = 1234"; 
     poster.Debugging = !UseZoho; 
     for (int i = 0; i < 1; i++)//newZoho.Count; i++) 
     { 
      var xmlString = Potential.GetPotentialXML(newZoho[i][1], newZoho[i][2], newZoho[i][4], newZoho[i][3], newZoho[i][5], newZoho[i][7], newZoho[i][0]); 
      Console.WriteLine("Sending New Records to Zoho: {0}", xmlString); 
      poster.PostItem.Set("xmlData", xmlString); 
      var result = poster.Post(3); 
      Console.WriteLine(result); 
      if (!string.IsNullOrEmpty(result)) 
      { 
       try 
       { 
        var rowLength = newZoho[i].Row.ItemArray.Length; 
        var rowOffset = Math.Abs((int)newZoho[i][rowLength - 1])-1; 

        potentialDatabaseDataSet.Potential.Rows[rowOffset]["ZohoID"] = ReadResult(result); 
        potentialTableAdapter.Update(potentialDatabaseDataSet.Potential.Rows[rowOffset]); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Failed to update: {0}", ex.Message); 
       } 
      } 
     } 
    } 

稱爲海報的位變量很好。它返回一個xml結果,其中有我的zohoID,我解析並嘗試存儲。出於測試目的,我嘗試只更新一條記錄。我得到了與potentialTableAdapter.Update(potentialDatabaseDataSet)的錯誤。對我來說奇怪的是,我用一個非常相似的代碼創造了一個全新的記錄,並且效果很好。事實上,我是如何在Soid = 1234的情況下創建該行的。我是唯一一個能夠訪問此程序的人,並且據我所知它不是多線程的,所以我只是不明白爲什麼它存在併發問題。請幫助:)

編輯

好了,所以我玩了一些,發現如果我添加一個EndEdit中給它我不明白的併發問題。另一方面儘管我綁定的datagridview顯示更新的數據,但實際上並沒有更新數據。所以這並不是說我回到原點,我認爲我其實很接近。我從記憶回事碼這個小一點,所以不恨,如果它不是right..it客人主要用於什麼我談論

 for (int i = 0; i < 5; i++) //emailRecord.Count; i++) 
     { 
      if (ZohoEmail.EmailExpectedShipping(emailRecord[i], "12/10/2012")) 
      {//true means that the email went through just fine 
       try 
       { 
        var rowLengh = emailRecord[i].Row.ItemArray.Length; 
        var rowOffset = Math.Abs((int)emailRecord[i][rowLengh - 1]) - 1; 

        potentialDatabaseDataSet.Potential.Rows[rowOffset][17] = true; //17 is Expected Email 
        potentialDatabaseDataSet.Potential.Rows[rowOffset].AcceptChanges(); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Failed to update: {0}", ex.Message); 
       } 
      } 
      potentialTableAdapter.Update(potentialDatabaseDataSet.Potential); 
     } 

    } 

回答

0

嗯,我想我想通了。非常感謝Marcin幫助我解決這個問題。你對我的生成的表格適配器中的問題是正確的。我最終根據自動生成的代碼創建了自己的代碼。這裏是我的代碼,只是在其他人遇到與自動生成代碼有關的問題。

using System; 
using System.Data.SqlServerCe; 
using System.Data.Common; 
using System.Data; 

namespace Zoho 
{ 
    public partial class PotentialTableAdapter 
    { 
     SqlCeDataAdapter _adapter; 
     SqlCeConnection _connection; 
     SqlCeTransaction _transaction; 
     SqlCeCommand[] _commandCollection; 
     DataTable _table; 

     public PotentialTableAdapter() 
     { 
      ClearBeforeFill = true; 
      InitConnection(); 
      InitAdapter(); 
      InitCommandCollection(); 
      FillTable(); 
     } 

     public bool ClearBeforeFill {get; set;} 
     public SqlCeDataAdapter Adapter 
     { 
      get 
      { 
       if ((this._adapter == null)) 
       { 
        this.InitAdapter(); 
       } 
       return this._adapter; 
      } 
     } 
     public SqlCeConnection Connection 
     { 
      get 
      { 
       if (_connection == null) 
        InitConnection(); 
       return _connection; 
      } 
     } 
     public SqlCeTransaction Transaction 
     { 
      get 
      { 
       return _transaction; 
      } 
      set 
      { 
       _transaction = value; 
       for (int i = 0; (i < CommandCollection.Length); i = (i + 1)) 
       { 
        CommandCollection[i].Transaction = value; 
       } 
       Adapter.DeleteCommand.Transaction = value; 
       Adapter.InsertCommand.Transaction = value; 
       Adapter.UpdateCommand.Transaction = value; 
      } 
     } 
     public SqlCeCommand[] CommandCollection 
     { 
      get 
      { 
       if ((this._commandCollection == null)) 
       { 
        InitCommandCollection(); 
       } 
       return this._commandCollection; 
      } 
     } 
     public DataTable Table 
     { 
      get 
      { 
       if (_table == null) 
        FillTable(); 
       return _table; 
      } 
     } 

    } 
} 
using System.Data.Common; 
using System.Data.SqlServerCe; 
using System.Data; 

namespace Zoho 
{ 

    partial class PotentialTableAdapter 
    { 
            private void InitAdapter() 
    { 
     this._adapter = new SqlCeDataAdapter(); 
     this._adapter.TableMappings.Add(GetTableMapping()); 
     this._adapter.SelectCommand = new SqlCeCommand("SELECT * FROM Potential", Connection); 
     this._adapter.InsertCommand = GetCommand(@"INSERT INTO [Potential] ([Soid], [SalesRep], [Account], [ClosingDate], [Amount], [Stage], [SourceId], [Product], [FirstName], [Email], [CustomerPO], [ZohoID], [WorkOrder], [ExpectedShip], [TrackingNumber], [DependencyID], [ProcessEmail], [ExpectedEmail], [ShippedEmail]) VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19)"); 
     this._adapter.UpdateCommand = GetCommand(@"UPDATE [Potential] SET [Soid] = @p1, [SalesRep] = @p2, [Account] = @p3, [ClosingDate] = @p4, [Amount] = @p5, [Stage] = @p6, [SourceId] = @p7, [Product] = @p8, [FirstName] = @p9, [Email] = @p10, [CustomerPO] = @p11, [ZohoID] = @p12, [WorkOrder] = @p13, [ExpectedShip] = @p14, [TrackingNumber] = @p15, [DependencyID] = @p16, [ProcessEmail] = @p17, [ExpectedEmail] = @p18, [ShippedEmail] = @p19 WHERE (([NCPotentialKey] = @p20))"); 
    } 
        private void InitConnection() 
    { 
     this._connection = new SqlCeConnection(Zoho.Properties.Settings.Default.PotentialDatabaseConnectionString); 
    } 
         private void InitCommandCollection() 
    { 
     _commandCollection = new SqlCeCommand[1]; 
     _commandCollection[0] = new SqlCeCommand("SELECT * FROM Potential", Connection); 

    } 
         private void FillTable() 
    { 
     _table = new DataTable(); 
     Adapter.Fill(_table); 
    } 

                               private DataTableMapping GetTableMapping() 
    { 
     var tableMapping = new DataTableMapping(); 

     tableMapping.SourceTable = "Table"; 
     tableMapping.DataSetTable = "Potential"; 
     tableMapping.ColumnMappings.Add("Soid", "Soid"); 
     tableMapping.ColumnMappings.Add("SalesRep", "SalesRep"); 
     tableMapping.ColumnMappings.Add("Account", "Account"); 
     tableMapping.ColumnMappings.Add("ClosingDate", "ClosingDate"); 
     tableMapping.ColumnMappings.Add("Amount", "Amount"); 
     tableMapping.ColumnMappings.Add("Stage", "Stage"); 
     tableMapping.ColumnMappings.Add("SourceId", "SourceId"); 
     tableMapping.ColumnMappings.Add("Product", "Product"); 
     tableMapping.ColumnMappings.Add("FirstName", "FirstName"); 
     tableMapping.ColumnMappings.Add("Email", "Email"); 
     tableMapping.ColumnMappings.Add("CustomerPO", "CustomerPO"); 
     tableMapping.ColumnMappings.Add("ZohoID", "ZohoID"); 
     tableMapping.ColumnMappings.Add("WorkOrder", "WorkOrder"); 
     tableMapping.ColumnMappings.Add("ExpectedShip", "ExpectedShip"); 
     tableMapping.ColumnMappings.Add("TrackingNumber", "TrackingNumber"); 
     tableMapping.ColumnMappings.Add("DependencyID", "DependencyID"); 
     tableMapping.ColumnMappings.Add("ProcessEmail", "ProcessEmail"); 
     tableMapping.ColumnMappings.Add("ExpectedEmail", "ExpectedEmail"); 
     tableMapping.ColumnMappings.Add("ShippedEmail", "ShippedEmail"); 
     tableMapping.ColumnMappings.Add("NCPotentialKey", "NCPotentialKey1"); 

     return tableMapping; 

    } 
              private SqlCeCommand GetDeleteCommand() 
    { 
     var deleteCommand = new SqlCeCommand(); 
     deleteCommand.Connection = this.Connection; 
     deleteCommand.CommandText = "DELETE FROM [Potential] WHERE (([NCPotentialKey] = @p1))"; 
     deleteCommand.CommandType = CommandType.Text; 
     var parameter = new SqlCeParameter("@p1", SqlDbType.Int, 0, ParameterDirection.Input, false, 0, 0, "NCPotentialKey", DataRowVersion.Original, null); 
     deleteCommand.Parameters.Add(parameter); 

     return deleteCommand; 
    } 
     private SqlCeCommand GetCommand(string text) 
     { 
      var command = new SqlCeCommand(text); 
      command.Connection = this.Connection; 
      command.Parameters.Add(new SqlCeParameter("@p1", SqlDbType.Int, 0,  ParameterDirection.Input, true, 0, 0, "Soid",   DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p2", SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "SalesRep",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p3", SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "Account",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p4", SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "ClosingDate", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p5", SqlDbType.Money, 0, ParameterDirection.Input, true, 0, 0, "Amount",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p6", SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "Stage",   DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p7", SqlDbType.Int, 0,  ParameterDirection.Input, true, 0, 0, "SourceId",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p8", SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "Product",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p9", SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "FirstName",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p10",SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "Email",   DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p11",SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "CustomerPO", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p12",SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "ZohoID",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p13",SqlDbType.Int, 0,  ParameterDirection.Input, true, 0, 0, "WorkOrder",  DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p14",SqlDbType.DateTime, 0, ParameterDirection.Input, true, 0, 0, "ExpectedShip", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p15",SqlDbType.NVarChar, 0, ParameterDirection.Input, true, 0, 0, "TrackingNumber",DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p16",SqlDbType.Int, 0,  ParameterDirection.Input, true, 0, 0, "DependencyID", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p17",SqlDbType.Bit, 0,  ParameterDirection.Input, true, 0, 0, "ProcessEmail", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p18",SqlDbType.Bit, 0,  ParameterDirection.Input, true, 0, 0, "ExpectedEmail", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p19",SqlDbType.Bit, 0,  ParameterDirection.Input, true, 0, 0, "ShippedEmail", DataRowVersion.Current, null)); 
      command.Parameters.Add(new SqlCeParameter("@p20",SqlDbType.Int, 0,  ParameterDirection.Input, true, 0, 0, "NCPotentialKey",DataRowVersion.Original, null)); 

      return command; 
     } 
    } 
} 

現在爲我的包裝類。我覺得這樣做很有用。使用系統的 ; using System.Data.SqlServerCe; using System.Data;

namespace Zoho 
{ 
    public class DatabaseConnection 
    { 
     PotentialTableAdapter table; 
     public DatabaseConnection() 
     { 
      table = new PotentialTableAdapter(); 
     } 
     public DataTable Table 
     { 
      get 
      { 
       return table.Table; 
      } 
     } 

     public void Update() 
     { 
      try 
      { 
       Console.Write("Attemping to update database: "); 
       table.Adapter.Update(Table); 
       Console.WriteLine("Success"); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Fail: {0}", ex.Message); 
      } 
     } 

    } 
} 

最後是代碼實際上很重要的代碼片段。馬辛幫我弄明白的那個。實際上它超級簡單。

 DatabaseConnection AllPotentials = new DatabaseConnection(); 
     var newZoho = AllPotentials.Table.DefaultView; 
     var poster = new ZohoPoster(ZohoPoster.Fields.Potentials, zohoPoster.Calls.insertRecords); 

     newZoho.RowFilter = "IsNull(ZohoID,'zoho') = 'zoho'"; 
     poster.Debugging = !UseZoho; //UseZoho= false which turns debugging on 

     for (int i = 0; i < 1; i++)//newZoho.Count; i++) 
     { 
      var xmlString = Potential.GetPotentialXML(newZoho[i]); 
      Console.WriteLine("Sending New Records to Zoho: {0}", xmlString); 
      poster.PostItem.Set("xmlData", xmlString); 
      var result = poster.Post(3); 
      Console.WriteLine(result); 
      if (!string.IsNullOrEmpty(result)) 
      { 
       try 
       { 
        newZoho[i].Row["ZohoID"] = ReadResult(result); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Failed to update: {0}", ex.Message); 
       } 
      } 
     } 
     try 
     { 
      Console.Write("Trying to update the database after getting zoho: "); 
      AllPotentials.Update(); 
      Console.WriteLine("Success"); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Failed: {0}", ex.Message); 
     } 

我嘗試過了,它說的成功,所以我在不同的程序打開數據庫和低看哪我的假數據具有ZOHO ID在它:)我太興奮了。現在我實際上可以啓動並運行這個程序。我現在遇到的唯一問題是,在我的datagridview中,它只顯示4或5條記錄而不是201條記錄(我只是想過它,我敢打賭,過濾器已經和它做了soemthign!)。現在完成我的程序,現在就可以完成它! :)再次感謝Marcin耐心地幫助我。既然你告訴我這個問題出現在我的tableAdapter中,我將把這個問題標記爲你的回答。

0

你不能只更新一行的想法。數據適配器允許更新表格,而不是行。因此,而不是

potentialTableAdapter.Update(potentialDatabaseDataSet.Potential.Rows[rowOffset]); 

使用

potentialTableAdapter.Update(potentialDatabaseDataSet.Potential); 

編輯

我不太清楚你想要達到什麼在這裏:

var rowLength = newZoho[i].Row.ItemArray.Length; 
var rowOffset = Math.Abs((int)newZoho[i][rowLength - 1])-1; 

它看起來像你首先獲得列數,哪個更好:

var rowLength = potentialDatabaseDataSet.Potential.Columns.Count; 

然後您根據最後一列中的值計算行數並獲得值之前的第一行。這是我不明白爲什麼?你也在計算基於視圖的行偏移量。

爲什麼你就是不使用:

newZoho[i].Row["ZohoID"] = ReadResult(result); 
potentialTableAdapter.Update(potentialDatabaseDataSet.Potential); 

,而不是哪一行,你應該更新計數?

我相信ZohoID是在更新之前存在於數據庫中的外鍵嗎?

EDIT 2

我認爲這個問題是與你的自動錶適配器。先以強類型的方式嘗試更新行:

((PotentialRow)newZoho[i].Row).ZohoID = ReadResult(result); 

並嘗試修改您的數據集適配器的更新查詢。自動數據適配器會生成非常難看的查詢。將更新查詢中的where子句更改爲僅對compary行主鍵(ID)現在是所有值。

+0

嗯,我試過它進出循環,我仍然得到併發問題。我不得不說,我相信可以更新1行,因爲我的表格適配器給了我更新(DataRow行)和(DataRow []行)的選項。 – 2012-04-12 20:07:16

+0

查看我編輯的答案 – Marcin 2012-04-13 07:19:49

+0

我之所以進行行計數等等是因爲ItemArray中的最後一個變量是該特定行來自整個表中的行偏移量。在這種情況下,它的價值是-21。很明顯,-21在我的數據庫中不是有效的行。所以我從第一張唱片開始計算,這是21個唱片到達新的Zeno [i]。這意味着在一個基於0的數組中,我將不得不使它成爲20.我不知道列計數位。這實際上看起來像它會工作,因爲它會返回11和行偏移量在列11(在基於zerobased的數組),所以謝謝你 – 2012-04-13 13:06:48