我正在尝试使用C#将新的DataRow(本地存储在DataSet中)插入到Access表中。该表也是由此应用程序创建的,有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()
是不可能的。
(使用Visual C#Express 2010,Access 2003)
答案 0 :(得分:1)
以下是完整的工作测试代码来说明该过程。我们需要做的就是提供一个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.");
}
}
}
答案 1 :(得分:0)
我首先想到的是,您的问题可能是AutoIncrementSeed
和AutoIncrementStep
都设置为-1
的负值。尝试将两者都设置为正值。
[编辑]
第二个想法,您可能想尝试OleDbCommandBuilder
(MSDN documentation here)。它使用DataSet的列信息自动创建INSERT,UPDATE和DELETE语句。
在我以前的雇主,我们在使用Access时一直使用OleDbCommandBuilder
,它就像魅力一样,即使有自动增量字段也是如此。