Вставьте новую строку данных с автоинкрементным первичным ключом с помощью C # (OleDB) - PullRequest
2 голосов
/ 20 декабря 2011

Я пытаюсь вставить новый DataRow (локально хранится в DataSet) в таблицу доступа с C #.Таблица также создается этим приложением и имеет 3 столбца:

  • ID (целое число, первичный ключ, Required установлено на No, хотя я установил его в качестве первичного ключа)
  • Name (строка)
  • 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();

КогдаОбновление Я всегда получаю

Индекс или первичный ключ не может содержать нулевое значение

Ошибка.

Установка значения Required дляСтолбец ID в Yes, выдаст

Индекс или первичный ключ не может содержать нулевое значение

Ошибка.

Как я могупозвольте Access назначить правильный первичный ключ и как мне вернуть новое значение в мой набор данных?

Использование SCOPE_IDENTITY() невозможно в Access, насколько я знаю, и найдено на некоторых форумах.

(Работа с Visual C # Express 2010, Access 2003)

Ответы [ 2 ]

1 голос
/ 08 декабря 2013

Ниже приведен полный рабочий тестовый код для иллюстрации процедуры. Все, что нам нужно сделать, это предоставить 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.");
        }
    }
}
0 голосов
/ 20 декабря 2011

Сначала я подумал, что ваша проблема может быть в том, что для AutoIncrementSeed и AutoIncrementStep установлено отрицательное значение -1. Попробуйте установить оба значения на положительное.

[EDIT]

Вторая мысль, вы можете попробовать OleDbCommandBuilder ( документация MSDN здесь ). Он автоматически создает операторы INSERT, UPDATE и DELETE, используя информацию о столбцах вашего DataSet. У моего бывшего работодателя мы все время использовали OleDbCommandBuilder при работе с Access, и это работало как чудо, даже с полями автоинкремента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...