RETURN_VALUE, DataAccesor
От: 10der  
Дата: 25.05.12 07:18
Оценка:
Добрый день.

Есть цель легко получать результат выполнения процедуры (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) {}


Спасибо!
Re: RETURN_VALUE, DataAccesor
От: fddima  
Дата: 25.05.12 11:02
Оценка:
Здравствуйте, 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 методов, в том числе и поэтому.
Re[2]: RETURN_VALUE, DataAccesor
От: Taison Россия  
Дата: 02.07.12 08:29
Оценка:
Здравствуйте, 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
Re[3]: RETURN_VALUE, DataAccesor
От: 10der  
Дата: 02.07.12 09:17
Оценка:
Здравствуйте, 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С-ников видно издалека...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.