gpt4 book ai didi

c# - 在 Mono 中使用 LINQ 插入 Sqlite 数据库会抛出 TargetInitationException 和 SqliteException

转载 作者:行者123 更新时间:2023-12-02 11:05:35 31 4
gpt4 key购买 nike

我正在尝试打开一个 Sqlite 文件并使用 Mono 将一行插入到表中。我引用了Mono.Data.Sqlite , System.Data ,和System.Data.Linq组件。 Sqlite 文件和表都存在。 Status类(class)有TableColumn属性。当我单独使用Mono的Sqlite库时,可以成功插入。

Status data = GetStatusFoo();
using (SqliteConnection con = new SqliteConnection("Data Source=" + Config.SQLITE_DB_FILE + ";Version=3;"))
{
con.Open();

using (SqliteCommand cmd = new SqliteCommand("INSERT INTO " + _table + _insert + " VALUES " + _values, con))
{
cmd.Parameters.Add(new SqliteParameter("@Timestamp", data.Timestamp));
// ...
cmd.ExecuteNonQuery();
}
con.Close()
}

但是,我不想输入 1000 个 SqliteParameters,因此我尝试使用 Linq-to-SQL。以下代码在DataContext中引发TargetInitationException构造函数。

Status data = GetStatusFoo();
using (DataContext db = new DataContext("Data Source=" + Config.SQLITE_DB_FILE + ";Version=3;"))
{
Table<Status> statuses = db.GetTable<Status>();
statuses.InsertOnSubmit(data);
db.SubmitChanges();
}

它提示 Version不是有效的关键字,因此当我删除它时,只留下

Status data = GetStatusFoo();
using (DataContext db = new DataContext("Data Source=" + Config.SQLITE_DB_FILE + ";")
{
Table<Status> statuses = db.GetTable<Status>();
statuses.InsertOnSubmit(data);
db.SubmitChanges();
}

它在 db.SubmitChanges() 处抛出 System.Data.SqlClient.SqlException “服务器不存在或连接被拒绝”。

但是,当我使用 SqliteConnection 作为 DataContext 的 IDbConnection 时,情况会发生变化,即

Status data = GetStatusFoo();
using (SqliteConnection con = new SqliteConnection("Data Source=" + Config.SQLITE_DB_FILE + ";"))
using (DataContext db = new DataContext(con))
{
Table<Status> statuses = db.GetTable<Status>();
statuses.InsertOnSubmit(data);
db.SubmitChanges();
}

这会抛出 Mono.Data.Sqlite.SqliteException: SQLite error unrecognized token: "@"db.SubmitChanges(); .

添加Version=3;回来没有帮助,并尝试 Version=2抛出 System.NotSupportedException。 Console 和 DataContext.Log 给出如下内容:

INSERT INTO [Status] ([Timestamp], ...) VALUES (@Timestamp, ...)
-- @Timestamp: Input Int64 (Size = 0; Prec = 0; Scale = 0) [1397710927]
-- ...
-- Context: SqlServer Model: AttributedMetaModel Build: 4.0.0.0
SELECT @@IDENTITY
-- @Timestamp: Input Int64 (Size = 0; Prec = 0; Scale = 0) [1397710927]
-- Context: SqlServer Model: AttributedMetaModel Build: 4.0.0.0

Unhandled Exception:
Mono.Data.Sqlite.SqliteException: SQLite error
unrecognized token: "@"

什么给了?为什么它不喜欢“@”符号?是否无法进行参数替换?或者是 @@IDENTITY最后调用?

编辑:附加信息

查看堆栈跟踪后,Mono.Data.SqliteCommand.BuildNextCommand 和 this.CommandText 中发生 SqliteException 异常。 == "SELECT @@IDENTITY" 。显然 SQLite 不支持这个 MS/Transact-SQL 命令。据我所知,为此创建了一个“outputCommand” DbLinq.Data.Linq.Sugar.Implementation.QueryRunner.Upsert (target={Status}, insertQuery={DbLinq.Data.Linq.Sugar.UpsertQuery})

所以我正在更改我的问题以包括:如何告诉 Linq 避免仅使用 SQL 命令?

最佳答案

我的问题得到了部分答案。

DbLinqProvider=sqlite; 添加到 SqliteConnection 查询字符串会告知 Linq-to-SQL 使用 SQLite 命令,并修复“SELECT @@IDENTITY” 问题。此代码有效:

Status data = GetStatusFoo();
using (SqliteConnection con = new SqliteConnection("Data Source=" + Config.SQLITE_DB_FILE + ";DbLinqProvider=sqlite;"))
using (DataContext db = new DataContext(con))
{
Table<Status> statuses = db.GetTable<Status>();
statuses.InsertOnSubmit(data);
db.SubmitChanges();
}

但是,我仍然必须使用 SqliteConnection 对象,因为 new DataContext("Data Source="+ Config.SQLITE_DB_FILE + ";DbLinqProvider=sqlite;")仍然抛出“服务器不存在或连接被拒绝”异常。

编辑:完整答案

事实证明,如果没有 DbLinqConnectionType 参数,DataContext 默认使用 System.Data.SqlClient.SqlConnection 进行连接。连接类型必须是程序集完全限定名称,因此以下代码适用于我:

// in Config
public static string SQLITE_CONNECTION_CLASS_AQN = typeof(Mono.Data.Sqlite.SqliteConnection).AssemblyQualifiedName


// in database class
static string _connection_string = "Data Source=" + Config.SQLITE_DB_FILE + ";DbLinqProvider=sqlite;DbLinqConnectionType=" + Config.SQLITE_CONNECTION_CLASS_AQN + ";";


// in database method
Status data = GetStatusFoo();
using (DataContext db = new DataContext(_connection_string))
{
Table<Status> statuses = db.GetTable<Status>();
statuses.InsertOnSubmit(data);
db.SubmitChanges();
}

仅供引用,typeof(Mono.Data.Sqlite.SqliteConnection).AssemblyQualifiedName 计算结果为 "Mono.Data.Sqlite.SqliteConnection, Mono.Data.Sqlite, Version=4.0.0.0 ,Culture=neutral,PublicKeyToken=0738eb9f132ed756"

关于c# - 在 Mono 中使用 LINQ 插入 Sqlite 数据库会抛出 TargetInitationException 和 SqliteException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23125190/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com