Как использовать выходной параметр с Insight.Database
Я изучаю Insight.Database и хотел бы преобразовать следующее для использования репозитория.
Эта версия работает:
using (SqlConnection connection = GetConnection())
{
string errorMessage = string.Empty;
connection.Open();
var selectCommand = new SqlCommand("cds_InsertUtilityIntroRate", connection);
selectCommand.CommandType = CommandType.StoredProcedure;
selectCommand.Parameters.Add(new SqlParameter() { ParameterName = "@utility_id", Value = introRateParameters.UtilityId });
selectCommand.Parameters.Add(new SqlParameter() { ParameterName = "@start_date", Value = introRateParameters.StartDate });
selectCommand.Parameters.Add(new SqlParameter() { ParameterName = "@intro_rate", Value = introRateParameters.IntroRate });
selectCommand.Parameters.Add(new SqlParameter() { ParameterName = "@commodity_id", Value = introRateParameters.CommodityId });
selectCommand.Parameters.Add(new SqlParameter() { ParameterName = "@zone", Value = introRateParameters.Zone });
var output = new SqlParameter() {ParameterName = "@error", DbType = DbType.String, Size = 1000};
output.Direction = ParameterDirection.Output;
selectCommand.Parameters.Add(output);
selectCommand.ExecuteNonQuery();
if (output.Value is string)
{
errorMessage = output.Value.ToString();
}
return errorMessage;
}
Вот что я собрал для хранилища:
public interface IIntroRateRespository
{
int cds_InsertUtilityIntroRate(int utility_id, int commodity_id, DateTime start_date, decimal intro_rate, string zone, string error);
}
Это код, который вызывает его через Insight.Database:
string errorMessage = string.Empty;
var conn = GetConnection();
var repository = conn.As<IIntroRateRespository>();
int results = repository.cds_InsertUtilityIntroRate(introRateParameters.UtilityId, introRateParameters.CommodityId, introRateParameters.StartDate,
introRateParameters.IntroRate, introRateParameters.Zone, errorMessage);
Console.Write(errorMessage);
Проблема в том, что есть выходной параметр, и я не уверен, как это должно быть связано. Когда я запускаю его, это ошибка с нулевой ссылкой исключение:
at Insight.Database.DBConnectionExtensions.<>c__DisplayClass10`1.<ExecuteScalar>b__f (IDbCommand _, IDataReader __) in c:\projects.net\Insight\Insight.Database\Insight.Database\Extensions\DBConnectionExtensions.cs:line 392
at Insight.Database.DBConnectionExtensions.ExecuteAndAutoClose[T](IDbConnection connection, Func`2 getCommand, Func`3 translate, CommandBehavior commandBehavior) in c:\projects.net\Insight\Insight.Database\Insight.Database\Extensions\DBConnectionExtensions.cs:line 1488
at Insight.Database.DBConnectionExtensions.ExecuteAndAutoClose[T](IDbConnection connection, Func`2 getCommand, Func`3 translate, Boolean closeConnection) in c:\projects.net\Insight\Insight.Database\Insight.Database\Extensions\DBConnectionExtensions.cs:line 1456
at Insight.Database.DBConnectionExtensions.ExecuteScalar[T](IDbConnection connection, String sql, Object parameters, CommandType commandType, Boolean closeConnection, Nullable`1 commandTimeout, IDbTransaction transaction, Object outputParameters) in c:\projects.net\Insight\Insight.Database\Insight.Database\Extensions\DBConnectionExtensions.cs:line 386
1 ответ
Чтобы использовать выходной параметр для реализации интерфейса, просто пометьте параметр как выходной параметр:
interface IFoo {
void MyProc(int inParameter, out outParameter, ref refParameter);
}
Так что для вас это должно быть просто:
public interface IIntroRateRespository
{
int cds_InsertUtilityIntroRate(int utility_id, int commodity_id,
DateTime start_date, decimal intro_rate, string zone, out string error);
}
Также, если ваш класс параметров выглядит так:
class IntroRateParams {
public int UtilityId;
public DateTime StartDate;
public decimal IntroRate;
public int CommodityId;
public string Zone;
public string Error;
}
Тогда вы можете просто определить интерфейс как:
public interface IIntroRateRespository
{
int cds_InsertUtilityIntroRate(IntroRateParams parameters);
}
Когда вы передаете один объект в метод, Insight попытается извлечь параметры из полей. Он также автоматически отражает выходные параметры обратно в объект. Так:
IntroRateParams p = /* from somewhere */
var repo = connection.As<IIntroRateRepository();
int id = repo.cds_InsertUtilityIntroRate(p);
var error = p.Error;
Что касается NullReferenceException: Insight генерирует NullReferenceException, поскольку вы определили интерфейс как возвращающий int. Insight вызывает ExecuteScalar и пытается привести результат к типу int, но ваша процедура не возвращает никаких строк.
Если ваша процедура не возвращает никаких строк, убедитесь, что ваш метод возвращает void.
public interface IIntroRateRespository
{
void cds_InsertUtilityIntroRate(int utility_id, int commodity_id,
DateTime start_date, decimal intro_rate, string zone, out string error);
}
Я обновлю библиотеку, чтобы исключение было яснее в этом случае.