2016-08-29 94 views
0

我剛開始使用Dapper。 Dapper工作正常。下一步,我試圖與Dapper Extension集成。它會生成一個名爲System.Data.OleDb.OleDbException的異常。"Additional information: Characters found after end of SQL statement."這是爲什麼? Dapper擴展不支持女士訪問(由於結束字符)或我的代碼問題,或者我錯過了一些東西。我的代碼如下Dapper擴展女士訪問System.Data.OleDb.OleDbException

using (var conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=myAccessFile.accdb;")) 
{ 
    conn.Open(); 
    conn.Insert<Person>(new Person { Name = "John Stan", Age = 20 }); 
} 
+1

嘗試找到一種方法來確定Dapper Extensions正在生成的SQL。也許它是在一次調用中結合INSERT和SELECT @@ IDENTITY語句。如果是這樣,那麼Access數據庫引擎會拋出你引用的錯誤。 –

+1

您可以爲實現DapperExtensions SqlDialectBase的MSAccess編寫自己的SqlDialect類。然後,您可以使用Access特定的SQL語句實現GetIdentitySql方法,以獲取最新記錄的ID。那麼你可以堅持Dapper擴展。在GitHub repo中有5個主要SQL引擎的實現:https://github.com/tmsmith/Dapper-Extensions/tree/master/DapperExtensions/Sql –

+1

@G Davison https://github.com/tmsmith/Dapper -Extensions /問題/ 79 – RobinAtTech

回答

3

根據一MSDN article

一些數據庫引擎,如在Microsoft Access Jet數據庫引擎,不支持輸出參數,無法處理在單個批處理多個語句。

所以問題是,插入方法生成的語句,如

INSERT INTO [Person] ([Person].[PersonName]) VALUES (@PersonName); 
SELECT CAST(SCOPE_IDENTITY() AS BIGINT) AS [Id] 

和Access不能處理它。

讀書,似乎是有關如何處理Access(MSDN文章建議第二個SELECT語句)時如何執行insert-and-get-new-record-key的建議,但這並沒有幫助如果您使用的是DapperExtensions庫,那麼它就是爲您生成查詢的。

所以,基本上,我認爲你認爲DapperExtensions不適用於Access是正確的。


在附註中,我做了一個惡夢,試圖找出正在生成的查詢。有各種文章談論註冊表黑客將「JETSHOWPLAN」值設置爲「ON」,但我無法讓其中任何一項工作。最後,我創建了包裝數據庫連接和命令類,以便在出路時捕獲查詢。如果這對將來的任何人有任何用處,我將其包括在下面。

數據庫連接初始化代碼需要稍微改變 - 例如,

var connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Database2.mdb;"; 
using (var conn = new WrappedDbConnection(new OleDbConnection(connectionString))) 
{ 
    conn.Insert<Person>(new Person { PersonName = "Dan" }); 
} 

和以下兩類需要定義 -

public class WrappedDbConnection : IDbConnection 
{ 
    private readonly IDbConnection _conn; 
    public WrappedDbConnection(IDbConnection connection) 
    { 
     if (connection == null) 
      throw new ArgumentNullException(nameof(connection)); 

     _conn = connection; 
    } 

    public string ConnectionString 
    { 
     get { return _conn.ConnectionString; } 
     set { _conn.ConnectionString = value; } 
    } 

    public int ConnectionTimeout 
    { 
     get { return _conn.ConnectionTimeout; } 
    } 

    public string Database 
    { 
     get { return _conn.Database; } 
    } 

    public ConnectionState State 
    { 
     get { return _conn.State; } 
    } 

    public IDbTransaction BeginTransaction() 
    { 
     return _conn.BeginTransaction(); 
    } 

    public IDbTransaction BeginTransaction(IsolationLevel il) 
    { 
     return _conn.BeginTransaction(il); 
    } 

    public void ChangeDatabase(string databaseName) 
    { 
     _conn.ChangeDatabase(databaseName); 
    } 

    public void Close() 
    { 
     _conn.Close(); 
    } 

    public IDbCommand CreateCommand() 
    { 
     return new WrappedDbCommand(_conn.CreateCommand()); 
    } 

    public void Dispose() 
    { 
     _conn.Dispose(); 
    } 

    public void Open() 
    { 
     _conn.Open(); 
    } 
} 

public class WrappedDbCommand : IDbCommand 
{ 
    private readonly IDbCommand _cmd; 
    public WrappedDbCommand(IDbCommand command) 
    { 
     if (command == null) 
      throw new ArgumentNullException(nameof(command)); 

     _cmd = command; 
    } 

    public string CommandText 
    { 
     get { return _cmd.CommandText; } 
     set { _cmd.CommandText = value; } 
    } 

    public int CommandTimeout 
    { 
     get { return _cmd.CommandTimeout; } 
     set { _cmd.CommandTimeout = value; } 
    } 

    public CommandType CommandType 
    { 
     get { return _cmd.CommandType; } 
     set { _cmd.CommandType = value; } 
    } 

    public IDbConnection Connection 
    { 
     get { return _cmd.Connection; } 
     set { _cmd.Connection = value; } 
    } 

    public IDataParameterCollection Parameters 
    { 
     get { return _cmd.Parameters; } 
    } 

    public IDbTransaction Transaction 
    { 
     get { return _cmd.Transaction; } 
     set { _cmd.Transaction = value; } 
    } 

    public UpdateRowSource UpdatedRowSource 
    { 
     get { return _cmd.UpdatedRowSource; } 
     set { _cmd.UpdatedRowSource = value; } 
    } 

    public void Cancel() 
    { 
     _cmd.Cancel(); 
    } 

    public IDbDataParameter CreateParameter() 
    { 
     return _cmd.CreateParameter(); 
    } 

    public void Dispose() 
    { 
     _cmd.Dispose(); 
    } 

    public int ExecuteNonQuery() 
    { 
     Console.WriteLine($"[ExecuteNonQuery] {_cmd.CommandText}"); 
     return _cmd.ExecuteNonQuery(); 
    } 

    public IDataReader ExecuteReader() 
    { 
     Console.WriteLine($"[ExecuteReader] {_cmd.CommandText}"); 
     return _cmd.ExecuteReader(); 
    } 

    public IDataReader ExecuteReader(CommandBehavior behavior) 
    { 
     Console.WriteLine($"[ExecuteReader({behavior})] {_cmd.CommandText}"); 
     return _cmd.ExecuteReader(); 
    } 

    public object ExecuteScalar() 
    { 
     Console.WriteLine($"[ExecuteScalar] {_cmd.CommandText}"); 
     return _cmd.ExecuteScalar(); 
    } 

    public void Prepare() 
    { 
     _cmd.Prepare(); 
    } 
} 

現在,查詢被髮送到數據庫之前寫入控制檯。