Получить идентификатор при вставке новой строки с помощью TableAdapter.Update в файловой базе данных - PullRequest
1 голос
/ 12 мая 2010

У меня есть таблица базы данных с одним полем, называемым ID, которое является целым числом с автоинкрементом. Используя TableAdapter, я могу читать и изменять существующие строки, а также создавать новые.

Однако, если я пытаюсь изменить вновь вставленную строку, я получаю исключение DBConcurrencyException:

 OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Shift.mdb;Persist Security Info=True");
 ShiftDataSetTableAdapters.ShiftTableAdapter shiftTA = new ShiftDataSetTableAdapters.ShiftTableAdapter();
 shiftTA.Connection = conn;

 ShiftDataSet.ShiftDataTable table = new ShiftDataSet.ShiftDataTable();
 ShiftDataSet.ShiftRow row = table.NewShiftRow();
 row.Name = "life";
 table.Rows.Add(row);
 shiftTA.Update(row); // row.ID == -1
 row.Name = "answer"; // <-- all fine up to here
 shiftTA.Update(row); // DBConcurrencyException: 0 rows affected

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

Я полагаю, что проблема в коде происходит от row.ID, который все еще равен -1 после первого вызова Update (). Вставка выполнена успешно, и в базе данных строка имеет допустимое значение ID.

Как я могу получить этот идентификатор, чтобы я мог продолжить второй вызов на обновление?

Обновление:

Похоже, что это можно было сделать автоматически, используя этот параметр . Однако, согласно ответу msdn social , драйверы OLEDB не поддерживают эту функцию.

Не знаете, куда идти, используйте что-то еще, кроме oledb?

Обновление:

Пробовал SQLCompact, но обнаружил, что у него такое же ограничение , он не поддерживает несколько операторов.

Последний вопрос: существует ли простая (на основе одного файла) база данных, которая позволила бы вам получить значения вставленной строки.

Ответы [ 2 ]

1 голос
/ 12 мая 2010

Попробуйте это http://support.microsoft.com/kb/815629, хотя пример кода есть в VB.NET.

Или, если многострочный запрос принят в MS Access и имеет встроенную функцию / переменную для получения последнего идентификатора, используйте это (хотя база данных SQLite): в любом случае, посмотрите, почему я получаю это "Нарушение параллелизма" в этих нескольких строках кода ??? Нарушение параллелизма: команда UpdateCommand затронула 0 из ожидаемых 1 записей , попробуйте Google для функции

[РЕДАКТИРОВАТЬ: работает на моем компьютере, у меня нет SQL Server Compact, но я не использовал несколько операторов]

public Form1()
{
    InitializeComponent();


    var c = Connect();

    var da = new SqlDataAdapter("select emp_id, emp_firstname, emp_lastname from emp where 1 = 0", c);



    var b = new SqlCommandBuilder(da);

    var getIdentity = new SqlCommand("SELECT CAST(@@IDENTITY AS INT)", c);

    da.InsertCommand = b.GetInsertCommand();
    da.UpdateCommand = b.GetUpdateCommand();
    da.DeleteCommand = b.GetDeleteCommand();
    da.RowUpdated += (xsender, xe) =>
    {
        if (xe.Status == UpdateStatus.Continue && xe.StatementType == StatementType.Insert)
        {
            xe.Row["emp_id"] = (int)getIdentity.ExecuteScalar();
        }
    };


    var dt = new DataTable();
    da.Fill(dt);

    var nr = dt.NewRow();
    nr["emp_firstname"] = "john";
    nr["emp_lastname"] = "lennon";


    var nrx = dt.NewRow();
    nrx["emp_firstname"] = "paul";
    nrx["emp_lastname"] = "mccartney";


    dt.Rows.Add(nr);
    dt.Rows.Add(nrx);

    da.Update(dt);

    dt.AcceptChanges();


    nrx["emp_lastname"] = "simon";
    da.Update(dt);

    nr["emp_lastname"] = "valjean";
    da.Update(dt);

}



SqlConnection Connect()
{
    return new SqlConnection(@"data source=.\SQLEXPRESS;Database=Test;uid=sa;pwd=hey");
}
0 голосов
/ 12 мая 2010

Почему бы не выбрать MAX (RowId), так как ваш RowId должен увеличиваться для каждой INSERT? Это возможно для вас?

Что касается вашего окончательного ответа, SQLite может быть идеальным инструментом для вас. Я надеюсь, что это так! И у него есть собственный поставщик данных .NET, поэтому нет необходимости в поставщиках OLEDB или ODBC.

...