2015-07-16 3 views
5

Recentemente ho avuto la causa di riportare solo un singolo valore oltre ai dati tabulari restituiti dalla stored procedure. Dal momento che EF non supporta le stored procedure con più set di risultati, ho pensato che avrei potuto farlo tramite un parametro di output. Tuttavia, utilizzando questo metodo ho riscontrato un problema in cui in I stavo ottenendo solo valori arrotondati per alcuni campi del valore numerico.Come utilizzare correttamente InOut ObjectParameter in EF4?

Il parametro alla mia stored procedure è stata dichiarata come:

@MyValue numeric(19,6) output 

Quando si chiama la funzione di mappatura, ho avuto:

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

Questo è ciò che sempre restituito il valore arrotondato al numero intero (vale a dire , scala zero).

primo luogo sono stato in grado di risolvere questo problema modificando manualmente il codice XML sottostante al edmx aggiungendo manualmente precisione e la scala attributi:

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

Questo è stato, non a caso, del tutto scartata la prossima volta ho eseguito " aggiorna modello dal database .."

mi sembra di aver risolto in modo più affidabile aggiornando la mia dichiarazione per la ObjectParameter in quanto tale:

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

Tuttavia, questo sembra un po 'terribile come un hack, e sono preoccupato per problemi in futuro (anche se si tratta solo di manutenzione per quanto riguarda questo numero magico). Esiste un modo migliore e affidabile per utilizzare i parametri di output all'interno di Entity Framework?

+0

I decimali in. NET mantengono le cifre così hai provato a utilizzare 0.0M o 0.000000M invece di vedere se funziona? Sarebbe almeno un po 'meno "magico", suppongo che stia tornando allo 0M predefinito (senza cifre) – XIU

+0

@XIU Non ho idea del motivo per cui lo fa, ma se passo 0..M con un numero qualsiasi di trascinamento zeri, quindi il 'myValue.Value' risultante è sempre 0. Inoltre, gli ObjectParameters successivi che invio alla query sono DBNull invece di essere impostati. Assolutamente bizzarro. –

+0

Possibile duplicato di http://stackoverflow.com/questions/18166992/decimal-output-parameter-rounded-to-inte-in-ef5-0 –

risposta

0

ho finito bisogno di questo in più posti, ora, così ho creato un metodo di supporto per esso:

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

Questo non esime l'uso dei numeri magici nel codice, ma almeno aiuta fornire una corrispondenza esatta tra ciò che vedi nel codice e ciò che vedi nel database. (per esempio, per un parametro proc memorizzato numeric(19,6), chiamerai Utility.SqlNumericMax(19, 6), quindi la relazione è più immediatamente evidente.)

Sembra che fornire il valore massimo al parametro prima della chiamata di processo memorizzata sia ancora il migliore e metodo più affidabile per la chiamata per popolare correttamente il risultato.

Problemi correlati