【问题标题】:DataAdapter: Update unable to find TableMapping['Table'] or DataTable 'Table'DataAdapter:更新无法找到 TableMapping['Table'] 或 DataTable 'Table'
【发布时间】:2013-10-14 05:58:29
【问题描述】:
这段代码sn-p抛出错误:
更新无法在适配器上找到 TableMapping['Table'] 或 DataTable 'Table'.)。Update(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);
【问题讨论】:
标签:
c#
sql-server
ado.net
dataadapter
【解决方案1】:
使用
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 来确定要更新的表有两个原因:
- 这将是低效的,因为它需要循环所有表及其所有行以查找具有
RowState 的行!= Unchanged
- 可能需要更新多个表,因为它们包含已更改的行。
DataAdapter 不支持此功能。因此DataAdapter.Update(DataSet) 假定默认名称"Table" 作为表名。
编辑:但是,也许有人可以解释一下为什么DataAdapter 不使用DataSet.Tables[0].TableName。
所以一般来说,最好的做法是指定要更新的表的名称。
【讨论】:
-
-
@ArifAnsari:不客气。但请考虑accept 的答案;)
【解决方案2】:
这是因为.NET 不能假定DataSet/DataTable 中的表名与数据库表相同。因此 .NET 会发出警告。
要解决它,您需要向DataAdapter 添加一个映射:
da.TableMappings.Add("TableNameInDb", "TableNameInTheDataSet");
但是,即使您在DataSet 或DataSource 中指定了名称,它仍然不起作用,因为适配器似乎忘记了名称。
我只是通过使用:
da.TableMappings.Add("Table", "TableNameInDb");
【解决方案3】:
我同意jgauffin,我只会用更多的文字来解释。
首先,我必须解释TableMapping 的工作原理。如果我们不指定TableMappings 和SqlDataAdapter(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";