使用c# (OleDB)插入带有自动递增主键的新DataRow

本文关键字:DataRow OleDB 插入 使用 | 更新日期: 2023-09-27 18:18:18

我试图插入一个新的DataRow(本地存储在一个数据集)到一个访问表与c#。这个表也是由这个应用程序创建的,有3列:

  • ID(整数,主键,Required设置为No,尽管我已将其设置为主键)
  • Name (string)
  • Money (int)

我当前的代码是这样的:

        OleDbConnection con = new OleDbConnection();
        OleDbCommand cmd = new OleDbCommand();
        OleDbDataAdapter da;
        DataSet ds = new DataSet();
        DataView dv = new DataView();
        DataRow row;
        string Con = @"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=";
        string path = "V:''ProjectProgress''Test.mdb";
        con.ConnectionString = Con + path;
        if (con.State == ConnectionState.Closed)
        {
            con.Open();
        }
        cmd.Connection = con;
        cmd.CommandText = "SELECT ID, Name, Money FROM Test";
        da = new OleDbDataAdapter(cmd);
        da.TableMappings.Add("Table", "Test");
        da.Fill(ds, "Test");
        ds.Tables["Test"].Columns[0].AutoIncrement = true;
        ds.Tables["Test"].Columns[0].AutoIncrementSeed = -1;
        ds.Tables["Test"].Columns[0].AutoIncrementStep = -1;
        dv.Table = ds.Tables["Test"];
        row = ds.Tables["Test"].NewRow();
        row["Name"] = "Huber";
        row["Money"] = 100;
        ds.Tables["Test"].Rows.Add(row);
        string strOLE = "INSERT INTO Test ([Name], [Money]) Values(@Name, @Money)";
        OleDbCommand cmdi = new OleDbCommand(strOLE, con);
        cmdi.Parameters.Add("@Name", OleDbType.VarChar, 25, "Name");
        cmdi.Parameters.Add("@Money", OleDbType.Integer, 4, "Money");

        da.InsertCommand = cmdi;
        da.Update(ds.Tables["Test"]);
        con.Close();

更新时,我总是得到一个

索引或主键不能包含Null值

错误。

ID列的Required值设置为Yes,将抛出

索引或主键不能包含空值

错误。

如何让Access分配正确的主键以及如何将新值返回到我的数据集中?

使用SCOPE_IDENTITY()是不可能的访问,据我所知和发现在一些论坛。

(使用Visual c# Express 2010, Access 2003)

使用c# (OleDB)插入带有自动递增主键的新DataRow

下面是演示该过程的完整工作测试代码。我们所需要做的就是提供一个OleDbDataAdapter.SelectCommand,其中包含主键和我们想要更新的列,然后OleDbCommandBuilder对象将为我们创建INSERT语句:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
namespace oleDbTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string myConnectionString;
            myConnectionString =
                    @"Provider=Microsoft.ACE.OLEDB.12.0;" +
                    @"Data Source=C:'Users'Public'Database1.accdb;";
            using (OleDbConnection con = new OleDbConnection())
            {
                con.ConnectionString = myConnectionString;
                con.Open();
                using (OleDbDataAdapter da = new OleDbDataAdapter())
                using (OleDbCommandBuilder bld = new OleDbCommandBuilder(da))
                {
                    bld.QuotePrefix = "[";  // these are
                    bld.QuoteSuffix = "]";  //   important!
                    da.SelectCommand = new OleDbCommand(
                            "SELECT [ID], [Name], [Money] " +
                            "FROM [Test] " +
                            "WHERE False",
                            con);
                    using (System.Data.DataTable dt = new System.Data.DataTable("Test"))
                    {
                        // create an empty DataTable with the correct structure
                        da.Fill(dt);
                        System.Data.DataRow dr = dt.NewRow();
                        dr["Name"] = "Huber";
                        dr["Money"] = 100;
                        dt.Rows.Add(dr);
                        da.Update(dt);  // write new row back to database
                    }
                }
                con.Close();
            }
            Console.WriteLine();
            Console.WriteLine("Done.");
        }
    }
}

我的第一个想法是,您的问题可能是AutoIncrementSeedAutoIncrementStep都设置为-1的负值。尝试将两者都设置为正值。

[编辑]

再考虑一下,您可能想尝试OleDbCommandBuilder (MSDN文档在这里)。它使用DataSet的列信息自动创建INSERT、UPDATE和DELETE语句。在我的前雇主,我们在使用Access时一直使用OleDbCommandBuilder,它工作得很好,即使有自动增量字段。