数据适配器:更新找不到表映射["表"]或数据表"表"



此代码片段抛出错误:

更新找不到表映射["表"]或数据表"表"。在适配器上。更新(ds(;线

为什么它会抛出这种类型的错误?

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);

使用

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. 可能需要更新多个表,因为它们包含更改的行。这不支持通过 DataAdapter .因此,DataAdapter.Update(DataSet)假定默认名称"Table"为表名。

编辑:但是,也许有人可以解释为什么DataAdapter不使用DataSet.Tables[0].TableName

因此,一般来说,最好指定要更新的表的名称。

这是因为 .NET 无法假定 DataSet/DataTable 中的表名与数据库表相同。因此,.NET 会向您发出警告。

要解决它,您需要在DataAdapter中添加映射:

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

但是,即使您在DataSetDataSource中指定了名称,它仍然不起作用,因为适配器似乎忘记了该名称。

我只是通过使用以下命令让它工作:

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

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

首先,我必须解释TableMapping是如何工作的。如果我们没有用SqlDataAdapter指定TableMappings(SqlDataAdapter将填充我们的DataSet(,那么默认情况下,第一个表将被命名为"Table",第二个将被命名为"Table1",第三个将被命名为"Table2"等。

所以,当我们想在DataSet中命名DataTable时,我们像这样使用它:

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";

最新更新