DataAdapter:更新无法找到TableMapping ['Table']或DataTable'Table'

时间:2013-10-07 15:21:57

标签: c# sql-server ado.net dataadapter

此代码段引发错误:

  

更新无法在adapter.Update(ds)上找到TableMapping ['Table']或DataTable'Table'。);线

为什么会抛出这种错误?

SqlConnection con = new SqlConnection();
con.ConnectionString = connectionString();

DataSet ds = new DataSet();

string strQuery = "SELECT * FROM Cars";
SqlDataAdapter adapter = new SqlDataAdapter();

adapter.SelectCommand = new SqlCommand(strQuery, con);

SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

adapter.Fill(ds, "Cars");

//Code to modify data in the DataSet
ds.Tables["Cars"].Rows[0]["Brand"] = "NewBrand";

adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(ds);

3 个答案:

答案 0 :(得分:8)

使用

adapter.Update(ds, "Cars");

代替。

我测试了它。没有相同的错误,如果我指定了表名,它就有效。但是,我必须承认,我还不知道为什么DataAdapter需要知道表名,因为它具有所需的所有信息。如果我使用ds.GetChanges,我会得到一行具有正确的表名。

更新我在MSDN上找不到任何内容,但最终在源代码中找到了它(ILSpy)。以下是DBDataAdapter.Update(DataSet)的实现:

public override int Update(DataSet dataSet)
{
    return this.Update(dataSet, "Table");
}

因此,如果您没有指定表,则使用表名"Table",如果您指定了除此之外的表名,您将收到此错误,这真的很奇怪!

我认为原因是DataAdapter无法调用GetChanges来确定要更新的表格,原因有两个:

  1. 由于需要循环所有表及其所有行以查找具有RowState!= Unchanged
  2. 的行,因此效率低下
  3. 可能需要更新多个表,因为它们包含已更改的行。 DataAdapter不支持此功能。因此DataAdapter.Update(DataSet)将默认名称"Table"视为表名。
  4. 修改:但是,也许有人可以解释为什么DataAdapter不会使用DataSet.Tables[0].TableName

    因此,一般来说,最佳做法是指定要更新的表的名称。

答案 1 :(得分:2)

这是因为.NET不能假设DataSet / DataTable中的表名与数据库表相同。因此,.NET警告你。

要解决此问题,您需要添加映射到DataAdapter

da.TableMappings.Add("TableNameInDb", "TableNameInTheDataSet");

但是,即使您在DataSetDataSource中指定了名称,它仍然无效,因为适配器似乎忘记了名称。

我只是通过使用它来实现:

da.TableMappings.Add("Table", "TableNameInDb");

答案 2 :(得分:0)

我同意jgauffin,我只会用更多文字来解释。

首先,我必须解释TableMapping的工作原理。如果我们未指定TableMappings SqlDataAdapterSqlDataAdapter将填充我们的DataSet),则默认情况下第一个表将命名为“Table”,第二个表将命名为“Table”命名为“Table1”,第三个将命名为“Table2”等。

因此,当我们想在DataTable中命名DataSet时,我们会像这样使用它:

System.Data.DataSet myDataSet = new System.Data.DataSet();

using (System.Data.SqlClient.SqlDataAdapter dbAdapter = new System.Data.SqlClient.SqlDataAdapter(dbCommand))
{
    dbAdapter.TableMappings.Add("Table", "Cars");
    dbAdapter.TableMappings.Add("Table1", "Trucks");
        //...

    dbAdapter.Fill(myDataSet);
}

只有这样我们才能像这样修改它:

myDataSet.Tables["Cars"].Rows[0]["Brand"] = "Toyota";
myDataSet.Tables["Trucks"].Rows[0]["Brand"] = "MAN";