ADO.net 2.0: PrimaryKey не обновляется после вызова DataAdapter.Update()

Я столкнулся с проблемой при обновлении типизированной DataTable со столбцом первичного ключа. В какой-то момент своего кода я заполняю таблицы данных (некоторые из них имеют столбцы первичного и внешнего ключей), а затем вставляю данные всех таблиц данных в одну транзакцию, используя адаптеры данных и функцию Update(). Поскольку типизированные таблицы данных не позволяют таблице PrimaryKey быть пустой, я вставляю туда несколько целочисленных значений. После вызова Update() я ожидал, что столбцы PK будут обновлены с помощью PK базы данных.

    public void UpdateMethod(DbTransaction transaction)
{
 DbDataAdapter dataAdapter = mDbProviderFactory.CreateDataAdapter();
 using (DbCommand insertCommand = CreateCommand())
 {
  insertCommand.Connection = mDbConnection;
  insertCommand.Transaction = transaction;
  dataAdapter.InsertCommand = insertCommand;
  dataAdapter.Update(dataTable);
 }

 // not sure if i need to do this:
 dataTable.AcceptChanges();

 // I would expect that databaseId is now the Id used in the database,
 // but it is the original Id which I set while creating the row entry
 databaseId = (int)dataTable.Rows[0]["Id"];
}

private DbCommand CreateCommand()
{
 // Make command object.
 DbCommand cmd = mDbProviderFactory.CreateCommand();

 // add command input parameters
 DbParameter parameter1 = mDbProviderFactory.CreateParameter();
 parameter1.ParameterName = mDatabaseParameterPrefix + "someColumn";
 parameter1.SourceColumn = "someColumn";
 parameter1.Size = 255;
 parameter1.DbType = DbType.String;

 // Output parameter
 DbParameter idParameter = mDbProviderFactory.CreateParameter();
 idParameter.ParameterName = mDatabaseParameterPrefix + "ID";
 idParameter.SourceColumn = "ID";
 idParameter.Direction = ParameterDirection.InputOutput;
 idParameter.DbType = DbType.Int32;

 // setup sql command
 cmd.Parameters.Add(parameter1);
 cmd.Parameters.Add(idParameter)
 cmd.CommandText = @"INSERT INTO [SomeTable] ([someColumn], ...) VALUES(@someColumn, ... ) SELECT CAST(SCOPE_IDENTITY() AS int) AS 'ID'";
 cmd.UpdatedRowSource = UpdateRowSource.Both;

 return cmd;
}

Спасибо за любые подсказки!


person phatoni    schedule 25.11.2009    source источник


Ответы (2)


Когда у вас есть первичный ключ, установленный при заполнении таблицы данных, он не будет перезаписывать уже существующие строки (однако, если он встретит соответствующий первичный ключ, он может или не может обновить неключевые элементы в зависимости от того, какой параметр загрузки установлен к)

Я полагаю, вам придется сначала очистить свой datatable, прежде чем вы его заполните.

person Mike Park    schedule 25.11.2009
comment
Вы правы, это может быть причиной. Но моя тестовая база данных уже пуста. Я также использую отрицательные числа в качестве временных закрытых ключей, а затем заполняю DataTable. - person phatoni; 26.11.2009

Решил это. Проблема заключалась в операторе SQL: вместо

INSERT INTO [SomeTable] ([someColumn], ...) VALUES(@someColumn, ...) SELECT CAST(SCOPE_IDENTITY() AS int) AS 'ID'

Это должно быть:

ВСТАВИТЬ В [SomeTable] ([someColumn], ...) VALUES(@someColumn, ...) SELECT @ID = SCOPE_IDENTITY()

В противном случае значение первичного ключа не присваивается выходному параметру.

person phatoni    schedule 15.12.2009