【问题标题】:VB.Net SQLite last_insert_rowid always return 1 using edmx (EF6)VB.Net SQLite last_insert_rowid 总是使用 edmx (EF6) 返回 1
【发布时间】:2016-03-11 08:16:57
【问题描述】:

我进行了大量研究,阅读了很多帖子,但没有发现将 edmx(实体数据模型)与 EF6 结合使用。 这是我的问题: 简单的表...

CREATE TABLE Oops (
OopsID INTEGER       NOT NULL
                     PRIMARY KEY AUTOINCREMENT,
UserID INTEGER       NOT NULL
                     REFERENCES Users (UserID),
Reason VARCHAR (100) NOT NULL

);

我正在尝试检索最后插入的 OopsID。 在 VB.Net 中,我尝试了以下方法:

Dim dbContext As New RCA.Entities
' 总是返回 1
Dim rtnVal1 As Int64 = dbContext.Database.ExecuteSqlCommand("INSERT INTO Oops (UserID,Reason) VALUES(" & clsShared.iUserID & ",'" & txtReason.Text & "'); SELECT last_insert_rowid() FROM Oops;")

' 总是返回 -1
Dim rtnVal2 = dbContext.Database.ExecuteSqlCommand("INSERT INTO Oops (UserID,Reason) VALUES(" & clsShared.iUserID & ",'" & txtReason.Text & "'); SELECT SEQ from sqlite_sequence WHERE name='Oops'; ")

但是 SQLiteStudio 中的以下查询返回正确的值 7:

SELECT SEQ from sqlite_sequence WHERE name='Oops'

似乎一个语句中的 2 个命令会在不同的连接上处理,我对此表示怀疑。

任何帮助表示赞赏。

【问题讨论】:

  • 你确定ExecuteSqlCommand 甚至支持多个语句?
  • 实际上,既然您提到了它,我只记得运行查询以在 DDL 中创建 2 个触发器,但只创建了 1 个。哦,天哪,我越来越意识到 SQLite 确实有点太轻了。好吧,如果你是对的(我怀疑你是对的),那么在多线程环境中没有安全的方法来检索最后插入的 ID,听起来像 ACCESS。我相信现在我在 rntVal1 中获得的值“1”可能只是创建的行数。
  • 实际上,我刚刚阅读了您对另一篇帖子 link 的回复,您在其中声明:“请注意,向 sqlite3_exec 提供两个命令不会在一个事务中执行它们;您必须实际执行 BEGIN/COMMIT命令。”你的意思是在一个声明中吗?如果是这样,您知道如何使用 EF6 处理事务吗?我知道要操作的唯一对象是 dbContext.Database,它只提供 BeginTransaction,没有 CommitTransaction,有点奇怪。
  • SQLite 本身可以做你想做的事,但我不知道 EF6 是如何工作的。无论如何,我建议阅读its documentation
  • 非常感谢,您为我指明了正确的方向。在做了更多阅读之后,我意识到我使用了错误的命令,“ExecuteSqlCommand”而不是“SqlQuery”......请参阅本文末尾的代码,它终于可以工作了。

标签: vb.net sqlite entity-framework-6


【解决方案1】:

这段代码终于为我工作了:

 使用 dbContextTransaction = dbContext.Database.BeginTransaction()
      尝试
        dbContext.Database.ExecuteSqlCommand("INSERT INTO Oops (UserID,Reason) VALUES(" & clsShared.iUserID & ",'" & txtReason.Text & "')")
        Dim rtnVal = dbContext.Database.SqlQuery(Of Int64)("SELECT last_insert_rowid();").ToList

        dbContextTransaction.Commit()
      将 generatedExceptionName 捕获为异常
        dbContextTransaction.Rollback()
      结束尝试
    结束使用

仅供参考,我最初从 ExecuteSqlCommand 获得的值“1”是受影响的行数。

【讨论】:

    【解决方案2】:

    你应该写

    SELECT SCOPE_IDENTITY()
    

    获取最后插入的id

    【讨论】:

    • 不在 SQLite 中,我不这么认为。
    • 测试后确认。我收到错误消息“SQL 逻辑错误或缺少数据库没有这样的功能:SCOPE_IDENTITY”
    猜你喜欢
    • 2015-05-18
    • 2020-11-03
    • 2022-09-23
    • 2016-11-21
    • 2019-10-10
    • 2014-04-13
    • 2017-03-20
    • 2013-11-04
    • 2011-12-09
    相关资源
    最近更新 更多