2015-07-16 15 views
5

Ich hatte kürzlich Ursache, um nur einen einzelnen Wert zusätzlich zu den Tabellendaten zurückzubringen, die von meiner gespeicherten Prozedur zurückgegeben werden. Da EF gespeicherte Prozeduren mit mehreren Ergebnismengen nicht unterstützt, konnte ich dies über einen Ausgabeparameter erreichen. Bei der Verwendung dieser Methode trat jedoch ein Problem auf, bei dem ich für einige Zahlenwertfelder nur gerundete Werte zurückerhalten konnte.Wie man InOut ObjectParameter in EF4 richtig verwendet?

Der Parameter für meine gespeicherten Prozedur deklariert wurde:

@MyValue numeric(19,6) output 

Wenn die Abbildungsfunktion aufrufen, ich hatte:

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

Dies ist, was immer den Wert auf eine ganze Zahl gerundet zurück (dh , Maßstab Null).

ich zuerst in der Lage war, dies den .edmx durch manuelles Hinzufügen von Genauigkeit und Skalierung Attribute der zugrunde liegenden XML-Bearbeitung manuell zu beheben:

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

Das war nicht überraschend, verworfen vollständig ich das nächste Mal durchgeführt " aktualisieren Modell aus der Datenbank ..“

ich scheine es behoben zu haben zuverlässiger durch die Aktualisierung meiner Erklärung für die ObjectParameter als solche:

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

Dies scheint jedoch sehr viel wie ein Hack zu sein, und ich bin besorgt über Probleme in der Zukunft (auch wenn es nur Wartung in Bezug auf diese magische Zahl ist). Gibt es eine bessere und zuverlässigere Möglichkeit, Ausgabeparameter innerhalb von Entity Framework zu verwenden?

+0

Dezimalstellen in .NET behalten ihre Ziffern, also haben Sie versucht, stattdessen 0.0M oder 0.000000M zu verwenden, um zu sehen, ob das funktioniert? Das wäre zumindest ein bisschen weniger "Magie", ich schätze, es fällt wieder auf die Standard 0M (ohne Ziffern) – XIU

+0

@XIU Keine Ahnung, warum es das tut, aber wenn ich 0..M mit einer beliebigen Anzahl von Nachlauf übergeben Nullen, dann ist der resultierende 'myValue.Value' immer 0. Zusätzlich sind die späteren ObjectParameters, die ich in die Abfrage sende, DBNull, anstatt gesetzt zu werden. Absolut bizarr. –

+0

Mögliches Duplikat von http://stackoverflow.com/questions/18166992/decimal-output-parameter-rounded-to-integer-in-ef5-0 –

Antwort

0

landete ich diese an mehr Orten brauchen, jetzt, so habe ich eine Hilfsmethode für sie:

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

Dies schließt nicht die Verwendung von magischen Zahlen in Code entbinden, aber zumindest es hilft Stellen Sie eine genaue Übereinstimmung zwischen dem, was Sie im Code sehen, und dem, was Sie in der Datenbank sehen, her. (z. B. für einen numeric(19,6) gespeicherten Prozessparameter rufen Sie auf, so dass die Beziehung augenscheinlicher wird.)

Es sieht so aus, als ob der maximale Wert für den Parameter vor dem gespeicherten Proc-Aufruf immer noch der beste ist zuverlässigste Methode für den Aufruf, um das Ergebnis korrekt aufzufüllen.

Verwandte Themen