title: NpgsqlCommandBuilder GetUpdateCommand throws exception
body: <p>I'm trying to use the NpgsqlCommandBuilder to automatically generate SQL commands to perform insert/update/delete operations on a dataset.  The dataset will be bound to a datagrid (which I really don't know how to do yet).  So I will not be manually editing the data set. When trying to automatically generate the sql commands, it will throw an exception when calling NpgsqlDataAdaptor.Update()</p>
  
  <p>Here is the schema for the db table:</p>
  
  <pre><code>tblFee
  {
      character(4) dest,
      character(4) id,
      character(2) indicator,
      double fee
  }
  the primary key is (dest, id, indicator)
  </code></pre>
  
  <p>Here is my code:</p>
  
  <pre><code>string m_strConnection = "Server=192.168.253.20;Port=5432;User Id=alex;Password=asdf;Database=mydb;";
  DataSet m_ds = new DataSet("EcnFeeData");
  NpgsqlConnection m_conn = new NpgsqlConnection(m_strConnection);
  NpgsqlDataAdapter m_dAdapter = new NpgsqlDataAdapter();
  m_dAdapter.SelectCommand = new NpgsqlCommand("SELECT * FROM \"tblFee\"", m_conn);
  NpgsqlCommandBuilder builder = new NpgsqlCommandBuilder(m_dAdapter);
  
  m_conn.Open();
  
  m_dAdapter.Fill(m_ds, "tblFee");
  
  m_ds.Tables[0].Rows[0]["fee"] = 1;
  
  builder.GetUpdateCommand();
  
  m_dAdapter.Update(m_ds, "tblFee");
  </code></pre>
  
  <p>This exception will get thrown while the last line is executing:</p>
  
  <pre><code>A first chance exception of type 'System.InvalidOperationException' occurred in System.Data.dll
  
  Additional information: Update requires a valid UpdateCommand when passed DataRow collection with modified rows.
  </code></pre>
  
  <p>The same thing happens when trying to insert a row, only the exception message is different:</p>
  
  <pre><code>Additional information: Update requires a valid InsertCommand when passed DataRow collection with new rows.
  </code></pre>
  
  <p>The last code example was an attempt to use the NpgsqlCommandBuilder the same way the SqlCommandBuilder is used in the example that is provided by the .NET 4.0 documentation.  The Npgsql documentation does not provide an example to do it this way.  Is this feature not supported in NpgsqlCommandBuilder?  I'd prefer to have the NpgsqlCommandBuilder automatically generate the sql commands, but if it doesn't work then I'll have to manually create them. </p>
  
  <p>After following the example in the Npgsql documentation for manually generating the InsertCommand, I was able to get it working, but I could not figure out how to do this for the UpdateCommand.  Here is the code I used to create the InsertCommand:</p>
  
  <pre><code>m_dAdapter.InsertCommand = new NpgsqlCommand("insert into \"tblFee\" (dest, id, indicator, fee) values (:a, :b, :c, :d)", m_conn);
  m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("a", DbType.AnsiStringFixedLength));
  m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("b", DbType.AnsiStringFixedLength));
  m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("c", DbType.AnsiStringFixedLength));
  m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("d", DbType.Double));
  
  m_dAdapter.InsertCommand.Parameters[0].Direction = ParameterDirection.Input;
  m_dAdapter.InsertCommand.Parameters[1].Direction = ParameterDirection.Input;
  m_dAdapter.InsertCommand.Parameters[2].Direction = ParameterDirection.Input;
  m_dAdapter.InsertCommand.Parameters[3].Direction = ParameterDirection.Input;
  
  m_dAdapter.InsertCommand.Parameters[0].SourceColumn = "dest";
  m_dAdapter.InsertCommand.Parameters[1].SourceColumn = "id";
  m_dAdapter.InsertCommand.Parameters[2].SourceColumn = "indicator";
  m_dAdapter.InsertCommand.Parameters[3].SourceColumn = "fee";
  m_dAdapter.InsertCommand.Connection = m_conn;
  </code></pre>
  
  <p>Here is my attempt to do the UpdateCommand, which doesn't work:</p>
  
  <pre><code>m_dAdapter.UpdateCommand = new NpgsqlCommand("update \"tblFee\" set dest = :a, id = :b, indicator = :c, fee = :d where dest = :e and id = :f and indicator = :g");
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("a", DbType.AnsiStringFixedLength));
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("b", DbType.AnsiStringFixedLength));
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("c", DbType.AnsiStringFixedLength));
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("d", DbType.Double)); 
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("e", DbType.AnsiStringFixedLength));
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("f", DbType.AnsiStringFixedLength));
  m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("g", DbType.AnsiStringFixedLength));
  
  m_dAdapter.UpdateCommand.Parameters[0].Direction = ParameterDirection.Input;
  m_dAdapter.UpdateCommand.Parameters[1].Direction = ParameterDirection.Input;
  m_dAdapter.UpdateCommand.Parameters[2].Direction = ParameterDirection.Input;
  m_dAdapter.UpdateCommand.Parameters[3].Direction = ParameterDirection.Input;
  m_dAdapter.UpdateCommand.Parameters[4].Direction = ParameterDirection.Input;
  m_dAdapter.UpdateCommand.Parameters[5].Direction = ParameterDirection.Input;
  m_dAdapter.UpdateCommand.Parameters[6].Direction = ParameterDirection.Input;
  
  m_dAdapter.UpdateCommand.Parameters[0].SourceColumn = "dest";
  m_dAdapter.UpdateCommand.Parameters[1].SourceColumn = "id";
  m_dAdapter.UpdateCommand.Parameters[2].SourceColumn = "indicator";
  m_dAdapter.UpdateCommand.Parameters[3].SourceColumn = "fee";
  m_dAdapter.UpdateCommand.Parameters[4].SourceColumn = "dest_orig";
  m_dAdapter.UpdateCommand.Parameters[5].SourceColumn = "id_orig";
  m_dAdapter.UpdateCommand.Parameters[6].SourceColumn = "indicator_orig";
  m_dAdapter.UpdateCommand.Connection = m_conn;
  </code></pre>
  
  <p>Any help would be much appreciated.</p>
  
  <p>Alex</p>