Cómo configurar la precisión decimal en OData
Estoy tratando de redondear la propiedad decimal usando escala, pero no está funcionando
public class Student
{
public Guid Id { get; set; }
public decimal Decimal { get; set; } = 0.000000m;
}
builder.EntitySet("Student");
var student = builder.EntityType();
student.Property(s => s.Decimal).Scale = 2;
Solicitud: https://localhost:44383/OData/Student
Resultado:
{
"@odata.context": "https://localhost:44383/OData/$metadata#Student",
"value": [
{
"Decimal": 0.000000,
"Id": "efb93e81-2729-40e2-bd0b-44dc338217f9"
}
]
}
Estoy esperando que el resultado sea
{
"@odata.context": "https://localhost:44383/OData/$metadata#Student",
"value": [
{
"Decimal": 0.00,
"Id": "efb93e81-2729-40e2-bd0b-44dc338217f9"
}
]
}
¿Cómo puedo arreglarlo?
EDIT:
Añadiendo Precision
Tampoco ayudó:
builder.EntityType().Property(s => s.Decimal).Precision = 2;
Pregunta hecha hace 3 años, 5 meses, 5 días - Por debugdynamo
3 Respuestas:
-
Parece que es cuestión de código fuente: https://github.com/OData/WebApi/issues/2384. Workarround:
public static decimal CalculateDecimalPrecision(decimal value, int precision) { if (ShouldCalculatePrecision(value, precision, out bool shouldRound)) { if (shouldRound) { value = Math.Round(value, precision); } else { var calculatedPrecision = decimal.Divide(1, Convert.ToDecimal(Math.Pow(10, precision))); var zeroAfterPoint = calculatedPrecision - calculatedPrecision; value += zeroAfterPoint; } } return value; } public class CustomODataPrimitiveSerializer : ODataPrimitiveSerializer { ///
/// Rewriting decimal value /// public override ODataPrimitiveValue CreateODataPrimitiveValue(object graph, IEdmPrimitiveTypeReference primitiveType, ODataSerializerContext writeContext) { if (graph is decimal decimalValue && primitiveType is EdmDecimalTypeReference decimalTypeReference && decimalTypeReference.Scale != null) { graph = CalculateDecimalPrecision(decimalValue, decimalTypeReference.Scale.Value); } return base.CreateODataPrimitiveValue(graph, primitiveType, writeContext); } }Respondida el Dec 18, 2020 a las 04:01 - por compilerczar
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás enfrentando es que estás intentando definir la precisión y escala de una propiedad decimal en tu modelo de datos, pero la configuración de precisión y escala en OData no afecta la serialización de los valores decimales en la respuesta. La precisión y escala en OData están relacionadas con la definición de los tipos de datos en el modelo de datos, pero no influyen en la representación de los datos cuando son serializados.
Por lo tanto, en el ejemplo que proporcionaste, la propiedad
Decimal
del objetoStudent
tiene una precisión predeterminada de 6 dígitos y una escala de 6 dígitos decimales, ya que estás inicializándola con0.000000m
.Para lograr el resultado que esperas en la serialización de la respuesta en formato OData, tendrás que manipular y formatear el valor de la propiedad
Decimal
antes de enviar la respuesta. Una forma de hacerlo es creando un ViewModel específico para esta operación.Aquí te dejo un ejemplo de cómo podrías implementar un ViewModel y un controlador para modificar la representación de la propiedad decimal en la respuesta:
- Crea un ViewModel para representar la respuesta con el formato deseado:
csharp public class StudentViewModel { public Guid Id { get; set; } public string DecimalRounded { get; set; } }
- En tu controlador, convierte la lista de estudiantes al formato del ViewModel antes de enviar la respuesta:
csharp [HttpGet] [EnableQuery] public IQueryable
GetStudents() { List students = / Obtener la lista de estudiantes de tu repositorio de datos /; var studentViewModels = students.Select(s => new StudentViewModel { Id = s.Id, DecimalRounded = s.Decimal.ToString("0.00") // Formatear el valor de Decimal con 2 decimales }); return studentViewModels.AsQueryable(); } Con esto, al realizar la solicitud a tu servicio OData, obtendrás la respuesta con la propiedad
DecimalRounded
con dos decimales, tal como lo esperas en el resultado. Recuerda ajustar el código según tu estructura y flujo de datos en tu aplicación.Respondida el Dec 19, 2020 a las 04:04 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Para configurar la precisión decimal en OData, debes utilizar el atributo
Precision
yScale
en la clase de entidad. El atributoPrecision
especifica el número total de dígitos en el valor decimal, mientras que el atributoScale
especifica el número de dígitos después del punto decimal.En tu caso, el código correcto sería:
builder.EntityType
().Property(s => s.Decimal).HasPrecision(4, 2); Esto establecerá la precisión del valor decimal en 4 dígitos, con 2 dígitos después del punto decimal.
Ten en cuenta que también debes asegurarte de que la columna de la base de datos que almacena el valor decimal tenga una precisión y escala adecuadas. Si la columna de la base de datos tiene una precisión o escala menor que la especificada en el modelo de entidad, el valor se truncará o redondeará según corresponda.
Respondida el Dec 19, 2020 a las 04:10 - por Gemini
Votos positivos: 0 | Votos negativos: 0