2014-01-20 2 views
0

Я просто играю с этим на данный момент, в конечном счете, я хочу прочитать CSV-файл в памяти, а затем вставить записи в SQL база данных. Существующие записи должны быть обновлены, записи, которые отсутствуют, должны быть добавлены. Однако записи, которые не существуют в новой CSV, не должны удаляться.Использование адаптера данных SQL для обновления и вставки строк не обновляется (только вставки)

Я играл вокруг примера из библиотеки MSDN. Я понимаю, что SqlDataAdapter может выполнять массовые обновления довольно быстро.

Я создал немного издеваться приложение с таблицей называется TempTestTable, который имеет TempTestTableId, Age и Name колонны. Я написал это (на основе MSDN Article):

using (SqlConnection connection = 
    new SqlConnection("data source=localhost;initial catalog=fishsticks;integrated security=True;MultipleActiveResultSets=True;")) 
{ 
    SqlDataAdapter dataAdpater = new SqlDataAdapter(
     "SELECT temptesttableid, Age, Name FROM TempTestTable", 
     connection); 

    dataAdpater.UpdateCommand = new SqlCommand(
     "UPDATE TempTestTable SET Age = @Age, Name = @Name " + 
     "WHERE TempTestTableId = @TempTestTableId", connection); 

    dataAdpater.InsertCommand = new SqlCommand(
     "INSERT INTO TempTestTable (Age, Name) " + 
     "VALUES (@Age, @Name)", connection); 

    SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
     "@TempTestTableId", SqlDbType.Int); 

    dataAdpater.InsertCommand.Parameters.Add(
     "@Age", SqlDbType.Int, 10, "Age"); 

    dataAdpater.InsertCommand.Parameters.Add(
     "@Name", SqlDbType.NVarChar, 50, "Name"); 

    dataAdpater.UpdateCommand.Parameters.Add(
     "@Age", SqlDbType.Int, 10, "Age"); 

    dataAdpater.UpdateCommand.Parameters.Add(
     "@Name", SqlDbType.NVarChar, 50, "Name"); 

    parameter.SourceColumn = "TempTestTableId"; 
    parameter.SourceVersion = DataRowVersion.Original; 

    DataTable tempTestTable = new DataTable(); 

    tempTestTable.Columns.Add("Age"); 
    tempTestTable.Columns.Add("Name"); 
    tempTestTable.Columns.Add("TempTestTableId"); 

    var row1 = tempTestTable.NewRow(); 

    row1["Age"] = 10; 
    row1["Name"] = "Smith"; 
    row1["TempTestTableId"] = 1; 

    var row2 = tempTestTable.NewRow(); 

    row2["Age"] = 40; 
    row2["Name"] = "Jones"; 
    row2["TempTestTableId"] = 2; 

    tempTestTable.Rows.Add(row1); 
    tempTestTable.Rows.Add(row2); 

    dataAdpater.Update(tempTestTable); 

Существует уже запись в базе данных с TempTestTableId = 1, поэтому идея в том, что в теории было бы обновить эту запись, а также вставить новую запись с идентификатором 2. Однако, когда я запускаю код, он вставляет оба элемента.

Любые идеи?

+1

Нет, 'DataAdapter' будет просто смотреть на' DataRow' годов [ 'RowState' собственности] (http://msdn.microsoft.com/ ан-нас/библиотека/system.data.datarowstate (v = vs.110) .aspx). Если это 'Added',' InsertCommand' будет выполнен, если он 'Modified', будет выполнен' UpdateCommand'. Сначала вы должны загрузить эту строку в таблицу из базы данных. –

+0

Первоначально пример, который я разорвал из MSDN, сделал это, но мне нужно загрузить из CSV, так как я могу читать из базы данных, а также из CSV? Должен ли я читать текущую таблицу базы данных в adatatable, затем прокручивать ее и вручную проверять каждую строку на моем CSV, изменять значения или вставлять новые строки и устанавливать RowState, а затем фиксировать их? – NibblyPig

+0

Вы можете заполнить пустой 'DataTable' с помощью« DataAdapter »и вашего' SelectCommand', включая два параметра. Если таблица пуста, вы можете добавить «DataRow» вручную, иначе вы можете изменить строки с обновленными значениями (если они есть) и вызвать 'dataAdpater.Update (tempTestTable)'. –

ответ

3

Нет, DataAdapter просто посмотрит на свойство RowState DataRow. Если это будет Added, будет выполнено InsertCommand, если будет выполнено ModifiedUpdateCommand. Сначала вы должны загрузить эту строку в таблицу из базы данных.

Вы можете заполнить пустые DataTable с помощью DataAdapter и вашего SelectCommand, включая два параметра. Если таблица пуста, вы можете добавить DataRow вручную, в противном случае вы можете изменить строки с обновленными значениями (если они есть) и вызвать dataAdpater.Update(tempTestTable).

Вот пример (непроверенные):

SqlDataAdapter dataAdpater = new SqlDataAdapter(
    "SELECT temptesttableid, Age, Name FROM TempTestTable WHERE Name = @Name", 
    connection); 

DataTable testTable = new DataTable(); 
// note that you should use an available csv-parser instead 
foreach (string line in File.ReadAllLines(path)) 
{ 
    string[] columns = line.Split(new char[]{'\t'}, StringSplitOptions.None); 
    if(columns.Length >= 2) 
    { 
     string name = columns[0].Trim(); 
     string ageStr = columns[1].Trim(); 
     int age; 
     if (int.TryParse(ageStr, out age)) 
     { 
      dataAdpater.SelectCommand.Parameters.AddWithValue("@Name", name); 
      int rowsAdded = dataAdpater.Fill(testTable); 
      if (rowsAdded == 0) 
      { 
       testTable.Rows.Add(name, age); 
      } 
      else 
      { 
       // update values? 
      } 
     } 
    } 
} 
dataAdpater.Update(testTable); 
+0

Спасибо, буду работать над этим. Я думаю, что в части значений обновлений я должен определить UpdateCommand и выполнить ее как-то. На самом деле я не уверен, как AddWithValue будет работать без определения AddCommand ... – NibblyPig

Смежные вопросы