3

我一直在使用带有 Ms Access 数据库的 Linq 数据映射。我像往常一样创建一个OleDbConnection并将其传递给DataContext.

到目前为止,这一直很好,可以根据复杂查询从表中检索数据,甚至关系也可以自动填充 1-N 关系中的子实体列表。

但是,当我尝试使用以下代码插入数据时:

    [Table(Name = "test_table")]
    public class test_item {
        [Column(IsPrimaryKey = true, IsDbGenerated = true)]
        public int field1;
        [Column]
        public int field2;
    }
    public void Test() {
        Table<test_item> tbl = this.GetTable<test_item>();
        test_item x = new test_item();
        x.field2 = 1222;
        tbl.InsertOnSubmit(x);
        this.SubmitChanges();
    }

我收到以下错误:

"Missing semicolon (;) at end of SQL statement."
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OleDb.OleDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult)
at System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(Expression query, QueryInfo[] queryInfos, IObjectReaderFactory factory, Object[] userArguments, ICompiledSubQuery[] subQueries)
at System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
at System.Data.Linq.ChangeDirector.StandardChangeDirector.DynamicInsert(TrackedObject item)
at System.Data.Linq.ChangeDirector.StandardChangeDirector.Insert(TrackedObject item)
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at MyClass.Test() in C:\...\MyClass.cs:line 123

如果我删除该IsDbGenerated标志,它不会崩溃,但在这种情况下,我被迫指定主键 ( x.field1 = 55),但我希望它自动分配。

如何避免出现此异常?

4

3 回答 3

3

我见过这个:)。您似乎在捎带 Linq2SQL 缺乏连接类型强制;)。Access 不支持 Linq2SQL,虽然由于 Access SQL 和 TSQL 的相似性,大多数读取查询和一些插入查询都可以工作,但其他事情根本不可行,其中之一就是使用自动标识列插入。原因是 Linq 生成两个查询作为同一个插入命令的一部分(一个用于插入记录,第二个用于检索新生成的标识),这与 Access 不兼容。一种解决方法是可能的,但相当难看,您需要对 DataContext 进行子类化,然后创建所有有问题的 Insert* 方法(在您的情况下为 InsertTest_Table),然后使用这些方法在同一事务中发出两个后续命令

void InsertTest_Table(Test_Table t)
{
    IDbCommand cmd;
    cmd = Connection.CreateCommand();
    cmd.Transaction = this.Transaction;
    cmd.CommandText = "INSERT INTO [Test_Table] ([Field2]) VALUES (@p0)";
    cmd.Parameters.Add(new OleDbParameter("p0", t.field2));
    cmd.ExecuteNonQuery();

    cmd = Connection.CreateCommand();
    cmd.Transaction = this.Transaction;
    cmd.CommandText = "SELECT @@IDENTITY";
    t.field1 = Convert.ToInt32(cmd.ExecuteScalar());
}

我的建议,如果可以的话,转储 Access 并切换到 SQLExpress(甚至 .SDF 更好)crea

于 2011-02-06T12:07:21.317 回答
1

听起来您正在使用 Linq to SQL。Linq to SQL 是为 SQL Server 而设计的,而不是 Access。

为什么不尝试使用 Linq to Entity?

我了解但从未这样做过,Access 具有必要的 ADO.NET 提供程序,因此它应该与 EF 一起使用。

于 2011-02-06T18:00:08.133 回答
0

您的代码生成已从 SQL Server 生成中删除,对于 SQL Server,MS SQL Server 不需要使用分号。尝试修改您的类的部分方法,使用此链接 - http://www.devart.com/linqconnect/docs/ExecuteDynamicMethods.html。也许它可以帮助你。

于 2011-02-21T16:35:25.703 回答