Добрый день.
Есть цель легко получать результат выполнения процедуры (exec @Issue = dbo.ProcName)
С ходу не получилось
Подскажите мысли, если не трудно.
public class CurrencyManager : BusinessManagerBase<CurrencyManager>
{
public CurrencyManager()
{
}
private CurrencyAccessor Accessor
{
get
{
return this.CreateDataAccessInstance<CurrencyAccessor>();
}
}
public GetCurrencyRatesResponse GetCurrencyRates()
{
var a = Accessor;
var x = a.GetCurrencyRates();
if (x != null) {}
if (a.err != 0) {}
}
}
[........]
public abstract class MyAccessor : SimpleAccessor
{
public int err = -1;
// за такой изврат нужно убивать...
protected override void Dispose(DbManager dbManager)
{
err = (int)dbManager.Parameter("@RETURN_VALUE").Value;
base.Dispose(dbManager);
}
}
public abstract class CurrencyAccessor : MyAccessor
{
[SprocName("dbo.p_GetCurrencyRates")]
public abstract List<ExchangeRateInfo> GetCurrencyRates();
}
Есть обходной вариант, но почему то прописывать каждый раз в процедуре доп параметр, которого нет в процах, да и еще с созданием класса ошибки, меня не прётЪ...
public abstract List<ExchangeRateInfo> GetCurrencyRates([Direction.ReturnValue("Error")] SQLExecReturnValue Error);
[...]
SQLExecReturnValue ret = new SQLExecReturnValue();
var x = Accessor.GetCurrencyRates(ret).ToArray();
if (x != null) {}
Спасибо!
Здравствуйте, 10der, Вы писали:
1>Есть цель легко получать результат выполнения процедуры (exec @Issue = dbo.ProcName)
1>С ходу не получилось
1>Подскажите мысли, если не трудно.
Ну можно попробовать замаппить @RETURN_VALUE на out параметр.
Стоит ещё опередлиться вот с этим:
а) генерировать ли исключения на RAISERROR или нет (их скорее всего
всегда прийдётся подавлять в коде, т.к. теперь мы анализируем return value, и тоже самое происходит внутри процедур, таким образом куча вываленных ошибок при нормальной работе — вполне нормальная ситуация, увы). Решается просто подменой DataProvider.
б) генерировать ли автоматически исключение если RETURN_VALUE != 1 (а здесь скорее всего всегда имеет смысл генерировать, но тогда сам RETURN_VALUE можно и не возвращать).
Я лично пункт б) решил просто расширив DbManager несколькими методами (DnExecute, DnExecuteList и т.п.) — мне этого хватило с головой, и в итоге реализация в лоб получилась короче и удобнее в использовании.
Для автоматизации выброса исключения можно попробовать поиграться с DbManager.OnAfterOperation, но там можно наткнутся на то, что значения параметров не будут доступны (всех ли параметров — не помню точно), но какие-то нюансы точно были, по крайней мере мне в итоге пришлось отказаться от OnAfterOperation в пользу банального враппнига ExecuteXxx методов, в том числе и поэтому.
Здравствуйте, fddima, Вы писали:
F> Ну можно попробовать замаппить @RETURN_VALUE на out параметр.
Подскажите как правильно замаппить @RETURN_VALUE на out параметр. Есть хранимая процедура для сохранения лица (person), которая в коде возврата возвращает идентификатор новой записи, либо ноль в случае ошибки или спорных вопросов. Список спорных вопросов (типа, существует похожее лицо) возвращается SELECT'ом. Переделать хранимую процедуру не представляется возможным, а для сохранения можно использовать только её.
База SQL Server 2000.
[ХранимаяПроцедура("xп_Лица_Сохранение_Лица")]
protected abstract Список<СпорныйВопросПриСохраненииЛица> СохранитьЛицо(ОперацияСохраненияЛица операция, bool операцияПодтверждена,
int? кодЛица,
String инн, String огрн, String окпо, String оконх, String оквэд, String кпп, String кодЖД,
String адресЮридический, String адресЮридическийЛат,
[Direction.ReturnValue("@RETURN_VALUE")] out int новыйКодЛица);
При выполнении возвращается ошибка
System.IndexOutOfRangeException: An SqlParameter with ParameterName '@новыйКодЛица' is not contained by this SqlParameterCollection.
at System.Data.SqlClient.SqlParameterCollection.GetParameter(String parameterName)
at System.Data.Common.DbParameterCollection.System.Data.IDataParameterCollection.get_Item(String parameterName)
at BLToolkit.Data.DataProvider.DataProviderBase.GetParameter(IDbCommand command, NameOrIndexParameter nameOrIndex)
in C:\projects\BLToolkit\Source\Data\DataProvider\DataProviderBase.cs:line 141
at BLToolkit.Data.DbManager.Parameter(String parameterName)
in C:\projects\BLToolkit\Source\Data\DbManager.cs:line 1345
Я перепробовал практически все варианты:
[Direction.ReturnValue("новыйКодЛица")] out int новыйКодЛица
[Direction.ReturnValue("@новыйКодЛица")] out int новыйКодЛица
[Direction.ReturnValue("@новыйКодЛица")] out int @новыйКодЛица
[Direction.ReturnValue("@RETURN_VALUE")] out int RETURN_VALUE
[Direction.ReturnValue("@RETURN_VALUE")] out int @RETURN_VALUE
Помогите пожалуйста. Ещё раз — база SQL Server 2000
Здравствуйте, Taison, Вы писали:
T>Здравствуйте, fddima, Вы писали:
T>T> [ХранимаяПроцедура("xп_Лица_Сохранение_Лица")]
T> protected abstract Список<СпорныйВопросПриСохраненииЛица> СохранитьЛицо(ОперацияСохраненияЛица операция, bool операцияПодтверждена,
T> int? кодЛица,
T> String инн, String огрн, String окпо, String оконх, String оквэд, String кпп, String кодЖД,
T> String адресЮридический, String адресЮридическийЛат,
T> [Direction.ReturnValue("@RETURN_VALUE")] out int новыйКодЛица);
T>
T>При выполнении возвращается ошибка
T>[code]
T>System.IndexOutOfRangeException: An SqlParameter with ParameterName '@новыйКодЛица' is not contained by this SqlParameterCollection.
T>Я перепробовал практически все варианты:
T>[Direction.ReturnValue("новыйКодЛица")] out int новыйКодЛица
T>[Direction.ReturnValue("@новыйКодЛица")] out int новыйКодЛица
T>[Direction.ReturnValue("@новыйКодЛица")] out int @новыйКодЛица
T>[Direction.ReturnValue("@RETURN_VALUE")] out int RETURN_VALUE
T>[Direction.ReturnValue("@RETURN_VALUE")] out int @RETURN_VALUE
T>Помогите пожалуйста. Ещё раз — база SQL Server 2000
1) @RETURN_VALUE — предустановленное имя возвращаемого результата процедуры. Это раз.
2) причем тут селекст в процедуре я не понял...
3) не совсем понял куда вернуть надо?
4) судя по ошибке неправильно передаете параметр
возвращать результат можно двумя варианта при создании.
так
[ScalarSource(ScalarSourceType.ReturnValue)]
public abstract int? Create(T entity);
или так
[ScalarSource(ScalarSourceType.ReturnValue)]
public abstract bool Insert([Direction.Output("Id")] T entity);
PS: 1С-ников видно издалека...