Могу ли я использовать DynamicParameters с Template и иметь возвращаемый параметр в dapper?

.net c# dapper

Вопрос

Система, в которой я сейчас работаю, использует хранимые процедуры для доступа к данным. Я смотрю на Dapper в данный момент (пока это выглядит великолепно), но мне было интересно, могу ли я использовать объект DynamicParameters, созданный с использованием шаблона, но сделать один из параметров параметром вывода. Например:

SP:

CREATE PROCEDURE InsertPerson
  @ID int Output,
  @Name varchar(100),
  @DOB DateTime2
AS
--INSERT STATEMENT

SET @ID = SCOPE_IDENTITY()

ПОКО:

internal class Person
{
  public int ID { get; set; }
  public string Name { get; set; }
  public DateTime DOB { get; set; }
}

Код:

var procParams = new DynamicParameters(person);
connection.Execute("InsertPerson", procParams, commandType: CommandType.StoredProcedure);

// This is where i'm having the issue, can it be done?
person.ID = procParams.Get<int>("ID");

Ток. Я получаю сообщение об ошибке, потому что ключ не найден. Есть ли способ получить параметр вывода ID без ручной настройки всех сохраненных параметров procs?

Принятый ответ

С помощью быстрой настройки « Add теперь заменяет значение из шаблона, позволяя:

public void TestProcWithOutParameter()
{
    connection.Execute(
        @"CREATE PROCEDURE #TestProcWithOutParameter
@ID int output,
@Foo varchar(100),
@Bar int
AS
SET @ID = @Bar + LEN(@Foo)");
    var obj = new
    { // this could be a Person instance etc
        ID = 0,
        Foo = "abc",
        Bar = 4
    };
    var args = new DynamicParameters(obj);
    args.Add("ID", 0, direction: ParameterDirection.Output);
    connection.Execute("#TestProcWithOutParameter", args,
                 commandType: CommandType.StoredProcedure);
    args.Get<int>("ID").IsEqualTo(7);
}

Это достаточно близко? Вы также можете использовать ParameterDirection.ReturnValue либо ранее существовавшего, либо нового значения. Обратите внимание, что он не обновляется непосредственно в исходном шаблоне; значение должно быть извлечено из экземпляра DynamicParameters (как показано).


Популярные ответы

Когда вы используете конструктор DynamicParameters для указания объекта шаблона, вам все равно нужно указать, что @ID является выходным параметром. Сначала, через шаблон, он будет установлен в ParameterDirection.Input . После его добавления он будет переопределен, чтобы иметь обновленные значения, после чего вы можете получить значение по имени параметра следующим образом:

procParams.Add("@ID", dbType: DbType.Int32, direction: ParameterDirection.Output);
// ... execute ...
person.ID = procParams.Get<int>("@ID");

Я смог получить эту работу и использовать ваши классы и код в дополнение к тому, что я показал выше.

EDIT: как описано в комментариях, хранимая процедура не принимает больше аргументов, чем заявила. Таким образом, альтернативный подход заключается в том, чтобы отбросить хранимую процедуру и обратиться к некоторому встроенному SQL. Когда вы используете запрос, Dapper будет игнорировать любые предоставленные ему параметры, которые не указаны в инструкции SQL. Это решение для решения этой проблемы:

string sql = "INSERT INTO Person (Name, DOB) VALUES (@Name, @DOB) SELECT SCOPE_IDENTITY()";
decimal id = conn.Query<decimal>(sql, procParams).First();
person.ID = (int)id;

Обратите внимание, что SCOPE_IDENTITY() возвращает десятичную, а не int.

Другая идея, которая, я думаю, не идеальна, заключается в изменении кода Dapper и добавлении метода Remove в класс DynamicParameters для удаления нежелательных параметров. Это не сэкономит вам много времени, поскольку вы все равно потратите время, указав, какие параметры удалять все, чтобы сделать хранимую процедуру счастливой. Если вы решите реализовать это, помните, что дело имеет значение при указании ключа для удаления из словаря parameters .



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему