2011-09-18 83 views
-5

我正在使用DataAdapter從具有主鍵的表填充DataSetADO.NET DataSet主鍵違例

如果我將主鍵列中的值更改爲另一行中已存在的值,則不會收到主鍵違例錯誤。

如果我在更改一行後調用DataSet.AcceptChanges(),以便現在有重複的主鍵值,則仍然沒有主鍵違例錯誤。

這是爲什麼?

string sqlcommand = "select * from itemmaster";//itemaster contains id field which is primary key// 

SqlConnection cn = new SqlConnection(connstring); 
cn.Open(); 
SqlCommand cmd = new SqlCommand(sqlcommand, cn); 

SqlDataAdapter da = new SqlDataAdapter(cmd); 

DataSet ds = new DataSet(); 
da.Fill(ds); 

ds.Tables[0].Rows[4]["ID"] = "2"; // value 2 already exists in another row 
+2

出於好奇,你爲什麼這樣做用'DataSet's,而不是一個ORM發展? –

+0

請參閱http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts –

+4

此外,如果您顯示代碼,您將得到更好的答案。創建一個顯示問題的小例子,然後在此處發佈示例。 –

回答

2

執行的任何限制,如你需要告訴DataSet有關源基礎架構主鍵約束。要做到這一點使用方法FillSchema()填充您的DataSet前:

da.FillSchema(ds, SchemaType.Source); 
da.Fill(ds); 

一個DataSet只是一個斷開的數據集。

當您從數據集中插入,更新或刪除行時,實際上並未直接更新數據庫。您只是將這些更改提交給斷開連接的一組數據。也就是說,當你這樣做:

ds.Tables[0].Rows[4].Delete(); 
ds.AcceptChanges(); 

所有你所做的是從Table[0]刪除一行,然後致力在DataSet是改變,而不是數據庫本身。要在數據庫本身中進行這種更改,您需要做一些不同的事情。

您需要添加一個「刪除命令」到DataAdapter。使用您的代碼爲例:

string sqlcommand = "select * from itemmaster";//itemaster contains id field which is primary key// 

SqlConnection cn = new SqlConnection(connstring); 
cn.Open(); 
SqlCommand cmd = new SqlCommand(sqlcommand, cn); 

SqlDataAdapter da = new SqlDataAdapter(cmd); 
SqlCommand deleteCmd = new SqlCommand("DELETE FROM itemmaster WHERE ID = @ID", cn); 
SqlParameter deleteParam = deleteCmd.Parameters.Add("@ID", SqlDbType.Int, 4, "ID"); 
deleteParam.SourceVersion = DataRowVersion.Original; 
da.DeleteCommand = deleteCmd; 

DataSet ds = new DataSet(); 
da.FillSchema(ds, SchemaType.Source, "itemmaster"); 
da.Fill(ds, "itemmaster"); 

ds.Tables[0].Rows[4].Delete(); 

da.Update(ds, "itemmaster"); 

欲瞭解更多信息,請參閱:

Updating Data Sources with DataAdapters

+0

感謝Kev爲您提供有用的信息 – funsukvangdu