Pedraz Pedraz - 26 days ago 12
C# Question

Comparing dates in Mongodb with C# LINQ driver

I have a MongoDB collection with a string field representing a date. In my C# app I map the results to a class with an aggregate field that convert that string to a DateTime object

[BsonIgnoreExtraElements]
public class Tweet
{
public ObjectId Id { get; set; }

[BsonElement("text")]
public string Texto { get; set; }

[BsonElement("created_at")]
public string Fecha { get; set; }

public DateTime FechaConvertida
{
get
{
var formato = "ddd MMM dd HH:mm:ss zzzz yyyy"; //'Sun Oct 23 19:42:04 +0000 2016'
var enUS = new CultureInfo("en-US");
var fechaConvertida = DateTime.ParseExact(this.Fecha, formato, enUS, DateTimeStyles.None);
return fechaConvertida;
}
}
}


Then on my api I make a query filtering elements between two dates (using 'CSharp Driver LINQ')

public IEnumerable<Tweet> GetTweetsDePeriodo(string nombreColeccion, int dias)
{
var hoy = DateTime.Today;
var fechaInicial = hoy.AddDays(-dias);

var coleccion = _db.GetCollection<Tweet>(nombreColeccion).AsQueryable<Tweet>();
var tweetsFiltrados = (from c in coleccion
where c.FechaConvertida >= fechaInicial
select c
).ToList();
return coleccion;
}


And then I get the following error:
*An unhandled exception occurred while processing the request.
InvalidOperationException: {document}.FechaConvertida is not supported


Any idea?
Thanks in advance,

Answer

Finally I've found a solution using a custom serializer for the Date field. This is how it looks like.

My class:

[BsonIgnoreExtraElements]
public class Tweet
{
    public ObjectId Id { get; set; }

    [BsonElement("text")]
    public string Texto { get; set; }

    [BsonElement("created_at")]
    [BsonSerializer(typeof(FechaTweetsSerializer))]
    public DateTime Fecha { get; set; }
}

And my custom serializer:

public class FechaTweetsSerializer : SerializerBase<DateTime>
{

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
    {
        context.Writer.WriteString(value.ToString(CultureInfo.InvariantCulture));
    }

    public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var fecha = context.Reader.ReadString();
        return ConvertirFecha(fecha);
    }

    private DateTime ConvertirFecha(string fechaFormatoTwitter)
    {
        var formato = "ddd MMM dd HH:mm:ss zzzz yyyy"; //'Sun Oct 23 19:42:04 +0000 2016'
        var enUS = new CultureInfo("en-US");
        var fechaConvertida = DateTime.ParseExact(fechaFormatoTwitter, formato, enUS, DateTimeStyles.None);
        return fechaConvertida;
    }
}

Hope it helps someone.

Comments