1

I'm working my way through a Plural Sight course to get some insight in MongoDB. It's one of the basic courses on the 'path' and it seems to have been made pre 2.0. As such I'm having some trouble understanding some of the subjects the tutor is going through.

I was hoping to see if someone could clarify how to Find any object based on their BsonID?

This is my object:

public class Patient
{
    [BsonElement("_id")]
    [BsonId]
    public string Name { get; set; }
    public ICollection<Ailment> Ailments { get; set; }
    public ICollection<Medication> Medications { get; set; }
}

And this is how I'm trying to query it:

    public HttpResponseMessage Get(int id)
    {
        var patient = _patients.Find(pat => pat._id == id).ToList();
        if(patient == null)
        {
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Patient Not Found..");
        }
        return Request.CreateResponse(HttpStatusCode.OK, patient); 
    }

This syntax doesn't allow me to build the project as there isn't a property with the name _id. I've also attempted to have an actual property ID, but that seems to create some sort of a problem when building (most likely since I already have an ID in it, created by BsonID).

I'm really sorry if this question has been asked before, but I seriously couldn't find any help on the subject. It seems like there should be a lot of resources on it (ie. us newbies should be able to get some good sources back when searching for something like "c# querying mongodb find on BsonId").

I fully understand if this is going to be down voted, but I'd really love it if someone with some time over could help me out here.

geostocker
  • 1,190
  • 2
  • 17
  • 29
  • I think this has [already been answered](https://stackoverflow.com/questions/6063219/how-to-manage-id-field-when-using-poco-with-mongodb-c-sharp-driver). – James Crosswell Jun 16 '17 at 10:43
  • Correct me if I'm wrong, but isn't `ObjectId` deprecated? At least when I attempted to use it instead of `BsonId` it was throwing me an error saying that there wasn't a property with that name in `BsonTypes` (or something similar). – geostocker Jun 16 '17 at 10:44
  • ObjectId is a type (like int or string) that is well suited to Id properties in Mongo... although in our recent projects we've gone with Guid instead of ObjectId because we didn't want to tightly couple all our models to Mongo (in case we wanted to change the persistence layer). BsonId is the attribute (BsonIdAttribute) that you'd decorate your Id field with if you don't want to go with the default `public ObjectId Id{ get; set; }` . – James Crosswell Jun 17 '17 at 09:14

2 Answers2

0

Your are putting together a C# query which doesn't know about the MongoDB mapping you specify in the attribute [BsonElement("_id")] on your POCO.

What you want is

var patient = _patients.Find(pat => pat.Name == id).FirstOrDefault();

EDIT (for clarification):

The MongoDB C# driver will dissect the filter expression pat => pat.Name == id and based on the attributes on your POCO it will create a MongoDB query for you that uses the "_id" field.

dnickless
  • 10,733
  • 1
  • 19
  • 34
0

The C# driver for Mongo requires an id field (some way to uniquely identify your documents). This can either be determined by convention or specified explicitly by you.

By convention, if you have a class with a public member of type ObjectId named Id then the C# driver for Mongo will assume this is your id and it will be mapped to a field called _id in your Mongo collection.

For example:

public class Widget
{
    public ObjectId Id { get; set; }
    public string Foo { get; set; }
}

If you don't want to go with the convention for some reason (for example if you have a natural key that you'd rather use) then you can use the BsonId attribute to tell the Mongo driver that you want to use some other field/type as your Id.

For example:

public class Widget
{
    [BsonId]
    public ObjectId WidgetId { get; set; }
    public string Foo { get; set; }
}

Or using a type other than ObjectID:

public class Widget
{
    [BsonId(IdGenerator=typeof(StringObjectIdGenerator))]
    public string WidgetId { get; set; }
    public string Foo { get; set; }
}
James Crosswell
  • 648
  • 4
  • 13