Search code examples
c#mongodbmongodb-.net-driver

Strongly typed Query not translated as expected


Working with C# and mongo I'm checking some of the different ways to query. Currently I have a collection of trips and each trip has an array of expenses. Each expence has it's own objectId.

First I had this query to locate a specific query to update. The trick was the secondpart where I dot my way into the id of the expense.

var Update = Query.And(
   Query<Trip>.EQ(t => t.Id, ObjectId.Parse(tripId)), 
   Query<Expense>.EQ( "Expenses._id", ObjectId.Parse(id)));

As I did a typo in here and named it Expenses._Id with a capital I I was looking for a way to move away from the "loose strings".

I tried this

var tripToUpdate = Query.And(
    Query<Trip>.EQ(t => t.Id, ObjectId.Parse(tripId)), 
    Query<Expense>.EQ(e => e.Id, ObjectId.Parse(id)));

But it got translated into

{ "$and" : [{ "_id" : ObjectId("5224f0208c74943810d333f6") }, 
            { "_id" : ObjectId("5224f0488c74943810d333f7") }] }

And not the expected Expense._id. I guess I would need some kind of convention for this to be supported.

Is it at all possible to write it in a more strongly typed manner men not only querying?

For querying I'm already using the std C# provider.


Solution

  • Based on the answer from @mnemosyn I came up with this solution improved by adding a downcast.

    After the great input I ended up using first the ElemenMatch, but after some further search on stackoverflow I spotted the downcast from IQueryable to an MongoQueryable as mentioned here

    Translate Queryable<T> back to IMongoQuery

    After this the code would be like:

    var query =
            .Trips.AsQueryable()
            .Where(c => c.Id == ObjectId.Parse(tripId) && c.Expenses.Any(p => p.Id == ObjectId.Parse(id)));
    

    Followed by a downcast to an MongoQuery

    var mongoQuery = ((MongoQueryable<Trip>) query).GetMongoQuery();
    

    Works really great.