2

Dapperを使い始めたばかりです。Dapper は正常に動作します。次のステップとして、Dapper Extension との統合を試みました。System.Data.OleDb.OleDbException という例外が生成されるの"Additional information: Characters found after end of SQL statement."はなぜですか? Dapper 拡張機能は Ms Access をサポートしていません (末尾の文字のため)、またはコードに問題があるか、何か不足しています。私のコードは以下です

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 });
}
4

1 に答える 1

7

MSDN の記事によると、

Microsoft Access Jet データベース エンジンなどの一部のデータベース エンジンは、出力パラメーターをサポートしておらず、単一のバッチで複数のステートメントを処理できません。

問題は、Insert メソッドが次のようなステートメントを生成していることです。

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

アクセスはそれを処理できません。

読んでみると、Access を扱うときに insert-and-get-new-record-key を実行する方法についてさまざまな提案があるようです (MSDN の記事では 2 番目の SELECT ステートメントが提案されています)。 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" });
}

そして、次の 2 つのクラスを定義する必要があります -

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();
    }
}

現在、クエリはデータベースに送信される前にコンソールに書き込まれます。

于 2016-09-02T12:14:59.927 に答える