1

I'm trying to read from a mongoDB collection with a Date filter (only the Date, time should be ignored):

var filterDefinition = Builders<SomeClass>.Filter.Eq(p => p.SomeDateTimeProperty.Date, DateTime.Now.Date);
using (var cursor = await _someCollection.FindAsync(filterDefinition))
{ ... }

SomeClass and the SomeDateTimeProperty property look like this:

[BsonIgnoreExtraElements]
[Serializable]
public class ReportConfiguration
{
    ...
    public DateTime SomeDateTimeProperty { get; set; }
    ...
}

The code throws an InvalidOperationException when trying to .FindAsync():

An exception of type 'System.InvalidOperationException' occurred in MongoDB.Driver.dll but was not handled in user code Additional information: Unable to determine the serialization information for p => p.SomeDateTimeProperty.Date

Everything works if I remove the .Date part in the filter (p.SomeDateTimeProperty.Date, DateTime.Now.Date), but I need a yyyy\mm\dd comparison regardless of the hh\mm.

Stacktrace says:

at MongoDB.Driver.ExpressionFieldDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.SimpleFilterDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
at MongoDB.Driver.IMongoCollectionExtensions.FindAsync[TDocument](IMongoCollection`1 collection, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
at [...]

What could be the issue?

Claudiu Constantin
  • 2,138
  • 27
  • 38

2 Answers2

2

Have you thought about using a between clause using Lt and Gt operators

 var b = Builders<SomeClass>.Filter;
 var date = DateTime.UtcNow.Date;
 var filter = b.And(
        b.Gte(x => x.SomeDateTimeProperty, date), 
        b.Lt(x => x.SomeDateTimeProperty, date.AddDays(1))
        );
 ...
pieperu
  • 2,662
  • 3
  • 18
  • 31
  • Yes, that's the current solution I approached and it works just fine, it's a good and clear workaround. However I am curious why the first approach doesn't work... – Claudiu Constantin Oct 17 '16 at 11:07
  • 1
    I think because .Date is a c# function on DateTime, that the MongoDb driver is unable to interpret when you try to apply it to a property on your Mongodb model property. You will find a lot of this when using the MongoDb c# driver, particularly when using Linq – pieperu Oct 17 '16 at 11:09
1

The Driver doesn't know how to serialize the Eq expression between two Dates.

Try doing ToString() to both Date parts:

var filterDefinition = Builders<SomeClass>.Filter.Eq(p => p.SomeDateTimeProperty.Date.ToString(), DateTime.Now.Date.ToString());

If that doesn't work, try something like this:

var date = DateTime.Now.Date.ToString();    
var docs = _someCollection.asQueryable().Where(p => p.SomeDateTimeProperty.Date.ToString() == date);
Axel Prieto
  • 535
  • 10
  • 20
  • Tried the first one, I get the same InvalidOperationException. For the second one I still get: 'An exception of type 'System.InvalidOperationException' occurred in MongoDB.Driver.dll but was not handled in user code. Additional information: {document}{SomeDateTimeProperty}.Date.ToString() is not supported' – Claudiu Constantin Oct 14 '16 at 06:41