2015-07-16 2 views
5

Недавно мне пришлось возвращать только одно значение в дополнение к табличным данным, возвращаемым моей хранимой процедурой. Поскольку EF не поддерживает хранимые процедуры с несколькими наборами результатов, я решил, что могу выполнить это с помощью выходного параметра. Однако, используя этот метод, я столкнулся с проблемой, когда я возвращал только округленные значения для некоторых полей числовых значений.Как правильно использовать InOut ObjectParameter в EF4?

Параметр моей хранимой процедуры был объявлен:

@MyValue numeric(19,6) output 

При вызове функции отображения, у меня было:

var myValue = new ObjectParameter("MyValue", typeof(decimal)); 
List<MyResultItem> results = this.ObjectContext.CallMyStoredProc(someId, myValue).ToList(); 

Это то, что всегда возвращает значение, округленное до целого числа (т.е. , шкала нуля).

я был первым в состоянии исправить это вручную редактируя основной XML в EDMX-вручную путем добавления точности и масштаб атрибуты:

<Parameter Name="MyValue" Type="numeric" Mode="InOut" Precision="19" Scale="6" /> 

Это было не удивительно, что полностью отбрасывается в следующий раз, когда я выполняемый " обновление модели из базы данных ..»

Я, кажется, установил ее более надежно, обновляя мое заявление для ObjectParameter как таковой:

var myValue = new ObjectParameter("MyValue", 999999999.999999M); 

Однако это кажется очень ужасным, как взломать, и я беспокоюсь о проблемах в будущем (даже если это просто обслуживание в отношении этого магического номера). Есть ли лучший и надежный способ использования выходных параметров в Entity Framework?

+0

Десятичные значения в .NET сохраняют свои цифры, поэтому вы попытались использовать 0.0M или 0.000000M вместо этого, чтобы узнать, работает ли это? Это, по крайней мере, было бы немного менее «волшебным», я предполагаю, что он возвращается к умолчанию 0M (без цифр) – XIU

+0

@XIU Не знаю, почему он это делает, но если я пройду 0..M с любым количеством трейлинг нули, то итоговое 'myValue.Value' всегда равно 0. Кроме того, более поздние объекты ObjectParameters, которые я отправляю в запрос, являются DBNull вместо набора. Абсолютно странно. –

+0

Возможный дубликат http://stackoverflow.com/questions/18166992/decimal-output-parameter-rounded-to-integer-in-ef5-0 –

ответ

0

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

/// <summary> 
/// Get the maximum allowed value for a SQL numeric of the specified scale and precision. 
/// </summary> 
/// <param name="scale">The scale.</param> 
/// <param name="precision">The precision.</param> 
/// <returns>Decimal representing the maximum value for the specified numeric.</returns> 
public static decimal SqlNumericMax(int scale, int precision) 
{ 
    return (decimal)Math.Pow(10, (scale - precision)) - (decimal)Math.Pow(10, (-1 * precision)); 
} 

Это не освобождает использование магических чисел в коде, но, по крайней мере, это поможет обеспечить точное соответствие между тем, что вы видите в коде, и тем, что вы видите в базе данных. (т. е. для параметра хранимой процедуры numeric(19,6), вы вызовете Utility.SqlNumericMax(19, 6), так что связь станет более очевидной.)

Похоже, что предоставление максимального значения параметру перед сохраненным вызовом proc по-прежнему является лучшим и самый надежный метод для правильного заполнения результата.

Смежные вопросы