Выполнить хранимую процедуру с параметрами в Dapper
Я использую щеголеватый (спасибо Сэм, отличный проект.) микро-ORM с DAL и по какой-то причине я не могу выполнять хранимые процедуры с входными параметрами.
в определенном сервисе у меня есть что-то вроде этого:
public void GetSomething(int somethingId)
{
IRepository<Something, SomethingEnum> repository = UnitOfWork.GetRepository<Something, SomethingEnum>();
var param = new DynamicParameters();
param.Add("@somethingId", dbType: DbType.Int32, value:somethingId, direction: ParameterDirection.Input);
var result = repository.Exec<Something>(SomethingEnum.spMyStoredProcedure, param);
...
}
когда выполнение хранимой процедуры происходит sqlexception бросается о том, что мне нужно предоставить 'somethingId'
процедура или функция 'spMyStoredProcedure' ожидает параметр '@somethingId', который не был предоставлен.
мой даль похожа на основе этого проекта на GitHub в Pencroff.
Я что-то пропустил?
обновление: я фактически передаю commandType через SomethingEnum:
public class SomethingEnum : EnumBase<SomethingEnum, string>
{
public static readonly SomethingEnum spMyStoredProcedure = new SomethingEnum("spMyStoredProcedure", "[dbo].[spMyStoredProcedure]", CommandType.StoredProcedure);
public SomethingEnum(string Name, string EnumValue, CommandType? cmdType): base(Name, EnumValue, cmdType)
{
}
}
4 ответов
вам нужно сказать ему тип команды: убедитесь, что есть commandType: CommandType.StoredProcedure
в вызове щеголя. В противном случае он просто выполняет текст:
spMyStoredProcedure
(С некоторыми неиспользуемыми параметрами в окружающем контексте). Это законный TSQL и пытается вызвать spMyStoredProcedure
без передачи параметров - то же самое, как если бы вы положили spMyStoredProcedure
в SSMS и нажмите Ф5.
кроме того, если ваши параметры фиксированы, я бы предложил просто использовать:
var param = new { somethingId };
или даже просто встроить его полностью:
var result = repository.Exec<Something>(SomethingEnum.spMyStoredProcedure,
new { somethingId }, commandType: CommandType.StoredProcedure);
(примечание: если ваш Exec<T>
метод только когда-либо обрабатывает хранимые процедуры, вы можете переместить commandType
внутренний для метода - или вы можете сделать его необязательным параметром, который по умолчанию равен CommandType.StoredProcedure
)
var queryParameters = new DynamicParameters();
queryParameters.Add("@parameter1", valueOfparameter1);
queryParameters.Add("@parameter2", valueOfparameter2);
await db.QueryAsync<YourReturnType>(
"{NameOfStoredProcedure}",
queryParameters,
commandType: CommandType.StoredProcedure)
вам нужно будет расширить его для поддержки исходящих параметров и возврата результатов, но он содержит часть для создания динамических параметров Dapper.
internal static bool ExecuteProc(string sql, List<SqlParameter> paramList = null)
{
try
{
using (SqlConnection conn = new SqlConnection (GetConnectionString()))
{
DynamicParameters dp = new DynamicParameters();
if(paramList != null)
foreach (SqlParameter sp in paramList)
dp.Add(sp.ParameterName, sp.SqlValue, sp.DbType);
conn.Open();
return conn.Execute(sql, dp, commandType: CommandType.StoredProcedure) > 0;
}
}
catch (Exception e)
{
//do logging
return false;
}
}
поскольку это был лучший результат для меня, но не было ответов, которые имеют дело с ExecuteNonQuery с параметрами таблицы, вот код для этого:
var queryParameters = new DynamicParameters();
queryParameters.Add("@Param0", datatable0.AsTableValuedParameter());
queryParameters.Add("@Param1", datatable1.AsTableValuedParameter());
var result = await ExecuteStoredProc("usp_InsertUpdateTest", queryParameters);
private async Task<Result<int>> ExecuteStoredProc(string sqlStatement, DynamicParameters parameters)
{
try
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
await conn.OpenAsync();
var affectedRows = await conn.ExecuteAsync(
sql: sqlStatement,
param: parameters,
commandType: CommandType.StoredProcedure);
return Result.Ok(affectedRows);
}
}
catch (Exception e)
{
//do logging
return Result.Fail<int>(e.Message);
}
}