Как получить возвращаемое значение из запроса с Dapper? - PullRequest
1 голос
/ 28 марта 2020

Я пытаюсь получить возвращаемое значение из запроса вставки, используя Dapper.

Вот как я пытаюсь заставить его работать:

// the query with a "returning" statement
// note : I have a trigger that sets the Id to a new value using the generator IF Id is null...
string SQL = "UPDATE OR INSERT INTO \"MyTable\" (\"Id\", \"Name\") " + "VALUES (@Id, @Name) RETURNING \"Id\"";
using (var conn = new FbConnection(MyConnectionString)) {
    var parameters = new DynamicParameters();
    parameters.Add("Id", null, System.Data.DbType.Int32);
    parameters.Add("Name", "newName", System.Data.DbType.String);
    // --- also add the returned parameters
    parameters.Add("retval", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
    // execute the query with Dapper....
    conn.Execute(SQL, parameters);
    // expecting the new ID here but it is ALWAYS null....!!!
    var newId = parameters.Get<object>("retval"); 
}

Теперь, чтобы убедиться, что мой запрос Хорошо, а не источник проблемы здесь, я реализовал подобный код с моим фактическим соединителем (в данном случае Firebird) следующим образом:

using (var conn = new FbConnection(MyConnectionString)) {
    FbCommand cmd = new FbCommand(SQL, conn);
    cmd.Parameters.Add("Id", null);
    cmd.Parameters.Add("Name", "newName");
    FbParameter pRet = cmd.Parameters.Add("retval", FbDbType.Integer);
    pRet.Direction = ParameterDirection.ReturnValue;
    conn.Open();
    cmd.ExecuteNonQuery();
    // => the new value is NOT null here, it returns the correct id!!
    var newId = Convert.ToInt32(pRet.Value);
    conn.Close();
}

В чем моя ошибка в коде Dapper? Почему одна версия в порядке, а НЕ другая? Я читал, что Dapper выполняет ExecuteNonQuery (), поэтому я не ожидаю, что это будет причиной.

1 Ответ

2 голосов
/ 28 марта 2020

Предложение returning действует как select в том смысле, что возвращает данные в таблице результатов. Таким образом, ваш запрос должен быть выполнен как запрос. Это также имеет то преимущество, что значительно упрощает вызывающий код:

var newId = conn.QuerySingle<int>(SQL, new { Id = (int?)null, Name = "newName" });

Если вам нужны дополнительные поля, это можно расширить, чтобы использовать пользовательский тип возврата, который соответствует возвращаемым столбцам или кортеж-значение. Например:

var row = conn.QuerySingle<MyTable>(SQL, new { Id = (int?)null, Name = "newName" });

или

var row = conn.QuerySingle<(int id, string name)>(SQL, new { Id = (int?)null, Name = "newName" });

- редактировать Вы можете получить доступ к возвращенным значениям с помощью

int iVal = row.Result.id;
string sVal = row.Result.name; 
...