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

C# 使用TableAdapter.Update在基于文件的数据库上插入新行时获取id,c#,database,sql-server-ce,jet,C#,Database,Sql Server Ce,Jet,我有一个数据库表,其中一个字段名为ID,是一个自动递增的整数。 使用TableAdapter,我可以读取和修改现有行以及创建新行 但是,如果尝试修改新插入的行,则会得到一个DBConcurrencyException: OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Shift.mdb;Persist Security Info=True"); ShiftDat

我有一个数据库表,其中一个字段名为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
OleDbConnection conn=new-OleDbConnection(@“Provider=Microsoft.Jet.OLEDB.4.0;Data-Source=Shift.mdb;Persist-Security-Info=True”);
ShiftDataSetTableAdapters.ShiftTableAdapter shiftTA=新的ShiftDataSetTableAdapters.ShiftTableAdapter();
连接=连接;
ShiftDataSet.ShiftDataTable=新的ShiftDataSet.ShiftDataTable();
ShiftDataSet.ShiftRow行=table.NewShiftRow();
row.Name=“生活”;
table.Rows.Add(行);
shiftTA.Update(行);//row.ID==-1
row.Name=“答案”// 为什么不选择最大值(RowId),因为您的RowId应该在每次插入时递增?这对你有可能吗

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

试试看,示例代码在VB.NET中

或者,如果MS Access中接受多行查询,并且该查询具有用于检索最后一个id的内置函数/变量,请使用此函数(尽管数据库是SQLite):,尝试使用谷歌搜索该函数

[编辑:在我的机器上工作,我没有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");
}

钩住RowUpdated事件并从那里分配关于最后一个问题(基于单个文件的数据库)的ID,Sqlite完全符合要求。看到我的答案了吗?我喜欢这个主意,但我还没有时间去研究,但我会的。我假设这将适用于我当前的自定义数据集/表/行。我会小心地查找最大值,因为另一个应用程序可能会在这两者之间插入一条新记录。在我的具体案例中,数据是唯一的,因此到目前为止,对所有列值的完整搜索解决了这个问题。你说得对,Phq,选择Max(Id)并不是一个真正简洁的解决方案,它基本上完成了任务。然而,正如Micheal Buen的回答中所述,我不知道SQL Server之外的@标识。这就是解决方案!=)