在基于文件的数据库上使用 TableAdapter.Update 插入新行时获取 id

发布于 2024-09-01 23:59:56 字数 1581 浏览 9 评论 0原文

我有一个数据库表,其中有一个名为 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,在第一次 Update() 调用后它仍然是 -1。插入成功,并且在数据库中该行具有有效的 ID 值。

如何获取该 ID 以便继续进行第二次更新调用?

更新:

看起来这可以使用此设置< /a>. 但是根据 msdn Social,OLEDB 驱动程序不支持此功能。

不知道从这里去哪里,使用 oledb 以外的东西吗?

更新:

尝试了 SQLCompact 但发现它具有相同的 限制,不支持多条语句。

最后一个问题:是否有任何简单的(基于单个文件的)数据库可以让您获取插入行的值。

I have a database table with one field, called ID, being an auto increment integer.
Using a TableAdapter I can read and modify existing rows as well as create new ones.

However if I try to modify a newly inserted row I get an 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

Separate question, is there any static type of the NewShiftRow() method I can use so that I don't have to create table everytime I want to insert a new row.

I guess the problem in the code comes from row.ID that is still -1 after the first Update() call. The Insert is successful and in the database the row has a valid value of ID.

How can I get that ID so that I can continue with the second Update call?

Update:

IT looks like this could have been done automatically using this setting.
However according to the answer on msdn social, OLEDB drivers do not support this feature.

Not sure where to go from here, use something else than oledb?

Update:

Tried SQLCompact but discovered that it had the same limitation, it does not support multiple statements.

Final question: is there any simple(single file based) database that would allow you to get the values of a inserted row.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

窝囊感情。 2024-09-08 23:59:57

试试这个 http://support.microsoft.com/kb/815629 ,示例代码是但在 VB.NET 中。

或者,如果 MS Access 接受多行查询并且它具有用于检索最后一个 id 的内置函数/变量,请使用它(尽管数据库是 SQLite): 无论如何,看看为什么我在这几行代码中得到这个“并发冲突” ???并发冲突:UpdateCommand影响了预期1条记录中的0条,尝试在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");
}

Try this http://support.microsoft.com/kb/815629 , the sample code is in VB.NET though.

Or if multiline query is accepted in MS Access and it has built-in function/variable for retrieving the last id, use this (the database is SQLite though): anyway see why I get this "Concurrency Violation" in these few lines of code??? Concurrency violation: the UpdateCommand affected 0 of the expected 1 records , try to google for the function

[EDIT: Works on my Machine, I don't have SQL Server Compact, but I didn't use multi-statement]

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");
}
反目相谮 2024-09-08 23:59:57

为什么不选择 MAX(RowId),因为每次插入时 RowId 都会增加?这对你来说可能吗?

至于您的最终答案,SQLite 可能是您的完美工具。我希望如此!而且它有自己的.NET 数据提供程序,因此不需要 OLEDB 或 ODBC 提供程序。

Why not select the MAX(RowId), as your RowId should increment for each INSERT? Is this possible for you?

As for your final answer, SQLite might be the perfect tool for you. I hope so! And it has its own .NET Data Provider, so no need for OLEDB or ODBC providers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文