2016-08-29 28 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(); 
    } 
} 

现在,查询被发送到数据库之前写入控制台。