Tengo datos en mi MongoDB donde estoy almacenando un int anulable, la mayoría de las veces como nulo. ¿Mi modelo en el lado de C# tiene la variable como int? MaterialID .
Cuando ejecuto .Query.FirstOrDefault() , aparece el error "La cadena de entrada no tenía el formato correcto". cada vez que intenta leer el valor nulo de Mongo (ints funciona bien).
Me las arreglé para solucionar esto cambiando mi int? a una cadena y luego devolviéndolo a un int?, pero ese es un truco horrible que realmente no me gusta. ¿Alguien tiene alguna idea sobre cómo puedo leer nulo de Mongo en mi int? en el lado de C#?
Gracias.
Mi JSON:
"Collection" : { "List" : [ { "ID" : "40", "StartDate" : ISODate("2013-01-01T00:00:00.000Z"), "EndDate" : ISODate("2013-12-31T00:00:00.000Z"), "MaterialID" : "3" }, { "ID" : "40", "StartDate" : ISODate("2014-01-01T00:00:00.000Z"), "EndDate" : ISODate("2014-09-30T00:00:00.000Z"), "MaterialID" : "null" } ]Está almacenando el campo MaterialID como cadena en la base de datos (tipo 2). Por supuesto, cuando intenta asignar un valor de cadena a un entero anulable, tiene un error. Nota: incluso null se almacena como una cadena con el texto "null" . Le recomiendo que comience por arreglar los datos en su base de datos. Puedes hacerlo desde mongo shell:
> db.collection.find({MaterialID:{$type:2}}).forEach( function(doc){ var materialId = (doc.MaterialID == "null") ? null : new NumberInt(doc.MaterialID); db.collection.update({_id:doc._id},{$set:{MaterialID: materialId}}); })Nota: en sus documentos json no tienen el campo _id, pero supongo que está allí en lugar del campo ID. De todos modos, puede ajustar el script a sus necesidades.
Después de cambiar el tipo de campo, su asignación a int anulable funcionará correctamente.
Por cierto, hay otra opción en caso de que, por algún motivo, no pueda corregir los datos en la base de datos. ¿Puede usar el serializador BSON personalizado que convertirá int? a la cadena y viceversa:
public class NullableIntAsStringSerializer : SerializerBase<int?> { public override void Serialize( BsonSerializationContext context, BsonSerializationArgs args, int? value) { context.Writer.WriteString(value.HasValue ? value.ToString() : "null"); } public override int? Deserialize( BsonDeserializationContext context, BsonDeserializationArgs args) { var str = context.Reader.ReadString(); return str == "null" ? (int?)null : Int32.Parse(str); } }Y asigna este serializador a tu propiedad
[BsonSerializer(typeof(NullableIntAsStringSerializer))] public int? MaterialID { get; set; }