2012-08-13 48 views
0

我遇到了使用DataAdapter的问题,我希望有人可以帮忙。基本上我创建一个系统,该系统如下:DataAdapter没有更新源文件

  1. 数据从一个数据源(MS-访问时,SQL Server或Excel)中读入,转换成数据表和插入到本地SQL Server数据库,使用DataAdapters。这一点工作正常。 SQL服务器表中有一个PK,它是一个自动增量设置为on的标识字段。
  2. 后续数据加载从源数据中读取数据,并将其与我们已有的数据进行比较。如果记录丢失,那么它被添加(这工作正常)。如果记录不同,则需要更新(这不起作用)。
  3. 在执行差分数据加载时,我创建一个数据表,它从目标表(SQL服务器)读取模式并确保它具有相同的列等。
  4. 目标表中的PK是列0当一个记录被插入时,第1列以后的所有值都被设置(如上所述,这是完美的)。我不会更改我添加的项目的行状态。数据表中的PK设置正确,我可以证实这一点。
  5. 更新数据时,我将第0列(PK列)设置为我正在更新的记录的值,并将所有列设置为与源数据相同。
  6. 对于更新的记录,我在行上调用AcceptChanges和SetModified以确保(我认为)应用程序调用正确的方法。
  7. 使用命令生成器,使用SelectCommand和UpdateCommand设置DataAdapter。

当我运行时,我使用SQL事件探查器来追踪它,并可以看到insert命令正在正确运行,但更新命令根本没有运行,这是问题的关键。作为参考插入表看起来像下面

PK Value1 Value 2 Row State 
== ====== ======= ========= 
124 Test1  Test 2 Added 
123 Test3  Test4  Updated 

几件事情要注意的....

  • 我已经通过加载行测试,将其改变成数据表,改变一些列字段和运行更新,这个工程。然而,这对于我的解决方案来说是不切实际的,因为数据是巨大的> 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; 
    } 
+0

作为参考,这是为3次修改和3所添加的数据表状态(第1栏是PK) 238281;变形 238298;变形 238306;变形 238307;增加 238308;增加了 238309;增加了 – Andrew 2012-08-13 10:59:52

+0

有些代码可以帮助我们识别问题。 – 2012-08-13 12:56:52

+0

编辑过的帖子以包含代码 – Andrew 2012-08-13 13:20:58

回答

0

如果有人有兴趣我还是设法避开这一问题,但从来没有成功让数据适配器工作。基本上,我所做的就是如下:

  • 创建索引和成员
  • 读入行的字段值的列表对象的列表已经改变和存储从源数据中的值(即该值将覆盖对象中的当前值)。此外,我创建一个逗号分隔的索引列表
  • 当我完成了我用的是逗号分隔的列表在SQL IN语句返回的行并将其加载到我的数据适配器
  • 对于每一个我运行一个LINQ查询索引并提取新值,更新数据集。这将行状态设置为已修改
  • 然后,我运行更新并正确更新行。

这不是最快或最好的解决方案,但它确实有效,并允许我在批处理中运行更改。

由于

安德鲁