2015-07-16 21 views
5

Son zamanlarda saklı yordamım tarafından döndürülen tablo verilere ek olarak tek bir değeri geri getirme nedenim oldu. EF, çoklu sonuç kümeleriyle saklı yordamları desteklemediğinden, bunu bir çıkış parametresi aracılığıyla gerçekleştirebileceğimi düşündüm. Ancak, bu yöntemi kullanarak, bazı sayısal değer alanları için yalnızca yuvarlanmış değerler aldığım bir sorunla karşılaştım.EF4'teki InOut ObjectParameter nasıl düzgün kullanılır?

@MyValue numeric(19,6) output 

haritalama işlevini çağırarak, ben toplam:

benim saklı yordam parametre ilan edildi

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

Bu her zaman bir tam sayıya yuvarlanır değer döndürdü nedir (yani sıfır ölçeği).

elle manuel Hassas eklenmesi ve Ölçek niteliklerini tarafından .edmx için altta yatan XML düzenleyerek bu sorunu gidermek mümkün ilk:

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

, şaşırtıcı olmayan, tamamen ben "gerçekleştirilen bir dahaki sefere atılır veritabanından Modeli güncelleyin .."

ben gibi ObjectParameter benim beyanı güncelleyerek daha güvenilir düzelttim gibi görünüyor:

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

Ancak, bu bir kesmek gibi korkunç bir şey gibi görünüyor ve gelecekte (sadece bu sihirli sayı ile ilgili bakım olsa bile) sorunları hakkında endişeliyim. Varlık Çerçevesi içindeki çıktı parametrelerini kullanmanın daha iyi ve güvenilir bir yolu var mı?

+0

.NET'teki ondalık basamaklar, bunların çalışıp çalışmadığını görmek için 0.0M veya 0.000000M kullanmayı denediniz mi? En azından biraz daha az "sihir" olurdu, sanırım varsayılan 0M'ye geri dönüyor (rakamsız) – XIU

+0

@XIU Bunu neden yaptığını bilmiyorum, ama herhangi bir sayı ile 0..M geçersem Sıfırlar, sonra oluşan 'myValue.Value' her zaman 0'dır. Ayrıca, sorguya gönderdiğim ObjectParameters, ayarlanmak yerine DBNull'dır. Kesinlikle tuhaf. –

+0

Olası kopya http://stackoverflow.com/questions/18166992/decimal-output-parameter-rounded-to-integer-in-ef5-0 –

cevap

0

şimdi daha çok yerde, bu ihtiyacı kadar sona erdi, bu yüzden bunun için bir yardımcı yöntemini yarattı:

/// <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)); 
} 

Bu kodda sihirli numaraların kullanılmasına kurtarmaz, ama en azından yardımcı olur Veritabanında gördüğünüz kodda gördüğünüz şey arasında tam bir eşleşme sağlayın. (yani, numeric(19,6) saklanan proc parametresi için Utility.SqlNumericMax(19, 6) numaralı telefonu arayacaksınız, böylece ilişki daha açık görünür.)

Kaydedilen proc çağrısı öncesinde parametreye maksimum değerin sağlanması hala en iyi ve Sonucun doğru bir şekilde doldurulması için en güvenilir yöntem.