Linq 数据与 Ms Access 数据库的映射:“SQL 语句末尾缺少分号 (;)。”

发布于 2024-10-16 03:58:30 字数 2472 浏览 3 评论 0原文

我一直在使用 Linq 数据映射与 Ms Access 数据库。我照常创建一个 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

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

我怎样才能避免出现此异常?

I've been using Linq data mapping with an Ms Access database. I create an OleDbConnection as usual and pass it to the DataContext.

This has worked fine until now, to retrieve data from tables based on complex queries, and even relations work to automatically populate a list of child entities in a 1-N relation.

However when I try to insert data using the following code:

    [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();
    }

I get the following error:

"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

If I remove the IsDbGenerated flag, it does not crash, but in that case I am forced to specify the primary key (x.field1 = 55), but I would like it to be assigned automatically.

How can I avoid getting this exception?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雨轻弹 2024-10-23 03:58:30

我见过这个:)。您似乎利用了 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

I've seen this :). You seem to be piggybacking on the Linq2SQL's lack of connection type enforcement ;). Linq2SQL is not supported on Access and while most read queries and some insert queries work due to similarity of Access SQL and TSQL, other things are simply not doable and one such thing is insert with auto-identity columns.
The reason is that Linq generates two queries as part of the same insert command (one to insert a record, second to retrieve the newly generated identity) and that doesn't sit well with Access. A workaround is possible but rather ugly, you need to subclass your DataContext and then create ALL problematic Insert* methods (in your case InsertTest_Table) and then use those methods to issue two consequtive commands inside a same transaction

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());
}

My suggestion, dump Access if you can and switch to SQLExpress (even .SDF is better)crea

若沐 2024-10-23 03:58:30

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

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

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

It sounds like you are using Linq to SQL. Linq to SQL is designed for SQL Server, not Access.

Why not try with Linq to Entities?

I understand, but have never done it, that Access has the necessary ADO.NET provider, so it should work with EF.

困倦 2024-10-23 03:58:30

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

Your code generation has left from SQL Server generation, for SQL Server it isn't necessary to have a semicolon for MS SQL Server. Try to modify partial methods for your classes, use this link - http://www.devart.com/linqconnect/docs/ExecuteDynamicMethods.html. Maybe it can help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文