我在使用 DataAdapter 时遇到了一个问题,希望有人能提供帮助。基本上我正在创建一个系统,如下所示:
- 使用 DataAdapters 从数据源(MS-Access、SQL Server 或 Excel)读取数据,转换为数据表并插入本地 SQL Server 数据库。这一点工作正常。SQL server 表有一个 PK,这是一个自动增量设置为 on 的标识字段。
- 随后的数据加载从源中读取数据并将其与我们已有的数据进行比较。如果记录丢失,则添加它(这工作正常)。如果记录不同,则需要更新(这不起作用)。
- 在进行差异数据加载时,我创建了一个数据表,它从目标表(SQL 服务器)中读取模式并确保它具有相同的列等。
- 目标表中的 PK 是第 0 列,因此当插入记录时,从第 1 列开始的所有值都会被设置(如前所述,这非常有效。)。我不会更改要添加的项目的行状态。数据表中的PK设置正确,我可以确认这一点。
- 更新数据时,我将第 0 列(PK 列)设置为我正在更新的记录的值,并将所有列设置为与源数据相同。
- 对于更新的记录,我在行上调用 AcceptChanges 和 SetModified 以确保(我认为)应用程序调用正确的方法。
- DataAdapter 使用命令生成器通过 SelectCommand 和 UpdateCommand 进行设置。
当我运行时,我使用 SQL 分析器对其进行了跟踪,可以看到插入命令正在正确运行,但更新命令根本没有运行,这是问题的症结所在。作为参考,插入表将类似于以下内容
PK Value1 Value 2 Row State
== ====== ======= =========
124 Test1 Test 2 Added
123 Test3 Test4 Updated
有几点需要注意......
- 我已经通过将要更改的行加载到数据表中,更改一些列字段并运行更新来测试这一点,这很有效。但是,这对我的解决方案来说是不切实际的,因为数据是 HUGE >1Gb,所以我不能简单地将其加载到数据表中而不会对性能造成巨大影响。我正在做的是创建最多 500 行的数据表并运行更新。初始数据加载期间的测试表明,这在内存使用和性能方面是最有效的。每个批次运行后数据表都会被清除。
有人对我在这里出错的地方有任何想法吗?
提前致谢
安德鲁
==========更新===============
以下是创建插入/更新行的代码
private static void AddNewRecordToDataTable(DbDataReader pReader, ref DataTable pUpdateDataTable)
{
// create a new row in the table
DataRow pUpdateRow = pUpdateDataTable.NewRow();
// loop through each item in the data reader - setting all the columns apart from the PK
for (int addCount = 0; addCount < pReader.FieldCount; addCount++)
{
pUpdateRow[addCount + 1] = pReader[addCount];
}
// add the row to the update table
pUpdateDataTable.Rows.Add(pUpdateRow);
}
private static void AddUpdateRecordToDataTable(DbDataReader pReader, int pKeyValue,
ref DataTable pUpdateDataTable)
{
DataRow pUpdateRow = pUpdateDataTable.NewRow();
// set the first column (PK) to the value passed in
pUpdateRow[0] = pKeyValue;
// loop for each row apart from the PK row
for (int addCount = 0; addCount < pReader.FieldCount; addCount++)
{
pUpdateRow[addCount + 1] = pReader[addCount];
}
// add the row to the table and then update it
pUpdateDataTable.Rows.Add(pUpdateRow);
pUpdateRow.AcceptChanges();
pUpdateRow.SetModified();
}
以下代码用于实际执行更新:
updateAdapter.Fill(UpdateTable);
updateAdapter.Update(UpdateTable);
UpdateTable.AcceptChanges();
以下用于创建数据表以确保其具有与源数据相同的字段/数据类型
private static DataTable CreateDataTable(DbDataReader pReader)
{
DataTable schemaTable = pReader.GetSchemaTable();
DataTable resultTable = new DataTable(<tableName>); // edited out personal info
// loop for each row in the schema table
try
{
foreach (DataRow dataRow in schemaTable.Rows)
{
// create a new DataColumn object and set values depending
// on the current DataRows values
DataColumn dataColumn = new DataColumn();
dataColumn.ColumnName = dataRow["ColumnName"].ToString();
dataColumn.DataType = Type.GetType(dataRow["DataType"].ToString());
dataColumn.ReadOnly = (bool)dataRow["IsReadOnly"];
dataColumn.AutoIncrement = (bool)dataRow["IsAutoIncrement"];
dataColumn.Unique = (bool)dataRow["IsUnique"];
resultTable.Columns.Add(dataColumn);
}
}
catch (Exception ex)
{
message = "Unable to create data table " + ex.Message;
throw new Exception(message, ex);
}
return resultTable;
}