[ADO.NET]設定SqlCommandBuilder建立的GetUpdateCommand使用PK Update
在查問題時,發現公司底層包的ADO在更新資料表時,Where條件是所有Table的欄位,覺得是否可以使用Primary Key來更新呢?
後來查到「can sqlcommandbuilder generate update command using primary key」,SqlCommandBuilder有個ConflictOption屬性(.net 2.0以上),預設更新是使用Select出來的欄位更新,所以改成「ConflictOption.OverwriteChanges」就可以用Primary Key更新了!
使用ConflictOption.OverwriteChanges要注意,Table一定要設Primary Key,不然會有「不會傳回任何重要資料行資訊的 SelectCommand 不支援 UpdateCommand 動態 SQL 的產生。」的錯誤哦!
測試程式如下(使用Northwind資料庫),
string connectionString = @"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;Connect Timeout=15;Application Name=ConflictOptionTest";
string queryString = @"SELECT * FROM dbo.Customers";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(queryString, connection);
//透過SqlDataAdapter建立SqlCommandBuilder
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
//SqlCommandBuilder.ConflictOption預設是CompareAllSearchableValues
MessageBox.Show("ConflictOption:" + builder.ConflictOption.ToString());
//Update的Where會是整個Table的欄位
MessageBox.Show(builder.GetUpdateCommand().CommandText);
//改成 WHERE 子句中都只包含 PrimaryKey 資料行
builder.ConflictOption = ConflictOption.OverwriteChanges;
MessageBox.Show("ConflictOption:" + builder.ConflictOption.ToString());
//Update的Where會變成了PrimaryKey CustomerID
MessageBox.Show(builder.GetUpdateCommand().CommandText);
//建立一個沒有PK的Table來試一下
//CREATE TABLE T1
//(
//C1 INT NOT NULL,
//C2 VARCHAR(10) NULL
//)
queryString = @"SELECT * FROM dbo.T1";
adapter.SelectCommand = new SqlCommand(queryString, connection);
builder = new SqlCommandBuilder(adapter);
MessageBox.Show(builder.GetUpdateCommand().CommandText);
//沒有PK會有「不會傳回任何重要資料行資訊的 SelectCommand 不支援 UpdateCommand 動態 SQL 的產生。」的錯誤!
}
環境
VS2010, .NET 2.0以上
參考資料
can sqlcommandbuilder generate update command using primary key
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^