I'm trying to get a document from database, but I can't do it in a desirable way. It seems handy to use this approach to retrieve data:
var filter = Builders<Book>.Filter.Eq(x => x.Id == new ObjectId(id), true);
var result = await coll.Find(filter).ToListAsync();
But in this case InvalidOperationException
is thrown when executing Find
method. Exception text:
Unable to determine the serialization information for x => (x.Id == new ObjectId(value(BookService.Controllers.ImportController+<>c__DisplayClass1_0).id)).
public class Book
{
[BsonId]
public ObjectId Id { get; set; }
public string Author { get; set; }
public string Title { get; set; }
}
Otherwise, when I use this filter:
var filter = Builders<Book>.Filter.Eq("_id", new ObjectId(id));
there are no any exceptions and result contains proper entity instances.
It seems that I need to implement custom serializer to determine that when x.Id
is used it means to search by _id
field, but I don't know how to do that. Or maybe there are some other ways to make this work?
This code is incorrect:
var filter = Builders<Book>.Filter.Eq(x => x.Id == new ObjectId(id), true);
Change it to this and it should fix your problem
var filter = Builders<Book>.Filter.Eq(x => x.Id, new ObjectId(id));
I always represent ObjectId as string in my C# models and use BsonRepresentation as an attribute to ensure correct serialization
[BsonRepresentation(BsonType.ObjectId)]
[BsonId]
public string Id { get; set; }
That way your queries just look like this:
var filter = Builders<Book>.Filter.Eq("_id", id);
var result = await coll.Find(filter).ToListAsync();
Or even better
var result = await coll.Find(x => x.Id == id).ToListAsync();