2014-04-17 16 views
1

我試圖打開一個Sqlite文件並使用Mono向表中插入一行。我參考了Mono.Data.SqliteSystem.DataSystem.Data.Linq組件。 Sqlite文件和表都存在。 Status類具有TableColumn屬性。當我單獨使用Mono的Sqlite庫時,我可以成功插入。在Mono中插入帶有LINQ的Sqlite數據庫引發TargetInvocationException和SqliteException

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構造函數中引發TargetInvocationException。

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()的「Server會拋出一個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。控制檯和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發生SqliteException異常,this.CommandText == "SELECT @@IDENTITY"。顯然,這個MS/Transact-SQL命令不被SQLite支持。從我可以告訴,一個「outputCommand」爲此創建DbLinq.Data.Linq.Sugar.Implementation.QueryRunner.Upsert (target={Status}, insertQuery={DbLinq.Data.Linq.Sugar.UpsertQuery})

所以我改變了我的問題,包括:我如何告訴Linq避免SQL只命令?

回答

1

我對我的問題有部分回答。

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"