When does the MongoDB C# Driver Get Data?
The key to understanding what is happening is understanding the differences between the MongoDB chain and LINQ.
If you’ve used LINQ, specifically LINQ Lambda queries, anywhere before then a function like this is familiar to you
List analysisObjects = analysisObjectRepository .FindAll() .Where(x => x.ID == packageId ) .Take(5) .ToList();
Now in LINQ each operation passes the result set to the next function in the chain. So if FindAll() returns 100 objects, those 100 objects will be passed to the Where() clause where they will be filtered down to say 50 objects. Then the Take(5) will filter those 50 objects down to 5 then finally the ToList() will take those 5 objects and return it into a list of type object.
How the MongoDB C# Driver Handles Chained Operations
Unlike LINQ the Mongo C# driver does not return a result set until the final operation.
UserNameMapping userMapping = db.GetCollection("UserProfile") .FindAs(Query.EQ("UserName", Username)) .SetLimit(1) .SetFields(Fields.Include("UserName")) .FirstOrDefault();
The final resulting query sent to the MongoDB.
So now this query works a little differently in that it won’t collect any information from the database until the SetFields() function fires. The purpose of this is to keep the performance high by only returning the specific data that is requested. The MongoDB API is capable of handling complex queries and return the final result set. You can think of it like a query builder. The reason for this difference is the concept of Freezing.
What is Freezing?
When you call FindAs() it returns a MongoCursor object and is unfrozen as it is passes that MongoCursor to SetLimit() where it adds the limit paramater to the MongoDB query and again returns an unfrozen MongoCursor. Finally the SetFields() will add only the UserName property to the fields you want returned in the document. (Note that _id is always returned unless specifically removed.)
When the FirstorDefault() is fired which is a LINQ function it kills the chain for MongoCursor. The driver will then freeze the MongoCursor object so no more changes can be made to the query and then will run the command returning the result from the Mongo database.