Re: C# SetRepresentation problem

278 views
Skip to first unread message

DaveC

unread,
Jun 11, 2013, 10:16:06 PM6/11/13
to mongod...@googlegroups.com
You need to set this on the collection:

var settings = new MongoCollectionSettings<Entity>(db, "CollectionOfEntityDocuments");
settings.AssignIdOnInsert = true;
var collection = db.GetCollection(settings);

Now when you insert in that collection, it will generate an ID.

In your class map, you can control what type of ID is generated by cm.IdMemberMap.SetIdGenerator().  For what you seem to want to do, you should use the MongoDB.Bson.Serialization.IdGenerators.StringObjectIdGenerator.  If you don't like the supplied ones, you can make you own that implements MongoDB.Bson.Serialization.IIdGenerator.

On Tuesday, June 11, 2013 12:26:05 PM UTC-4, Mark Farmiloe wrote:
I'm just trying out the C# driver and was following through the example in the 'Getting Satrted with CSharp Driver' page, except I wanted to use a string representation of the ObjectId.
So I added:
BsonClassMap.RegisterClassMap<Entity>(cm => {
  cm.AutoMap();
  cm.IdMemberMap.SetRepresentation(BsonType.ObjectId);
});
However when I stepped through the code, the first entity inserted had an Id of null. I checked this using the mongo shell.
So I tried changing the mapping line to 
  cm.IdMemberMap.SetRepresentation(BsonType.ObjectId).SetIgnoreIfNull(true);
That hack worked to the extent that the the entity gained an ObjectId (per mongo shell), but didn't populate the Id field in the code.
Another post suggests that my initial code should have worked.
So is this a bug, or just me being thick?
 
Thanks
Mark
 

Mark Farmiloe

unread,
Jun 12, 2013, 4:12:30 AM6/12/13
to mongod...@googlegroups.com
Thanks DaveC, but that didn't work... 
        public class Entity
        {
            public string Id { getset; }
            public string Name { getset; }
        }
...
            BsonClassMap.RegisterClassMap<Entity>(cm => {
                cm.AutoMap();
                cm.IdMemberMap.SetRepresentation(BsonType.ObjectId).SetIgnoreIfNull(true);
            });
            var connectionString = "mongodb://localhost";
            var client = new MongoClient(connectionString);
            var server = client.GetServer();
            var database = server.GetDatabase("test");
            var settings = new MongoCollectionSettings<Entity>(database, "entities");
            settings.AssignIdOnInsert = true;
            var collection = database.GetCollection<Entity>("entities", settings);
            var entity = new Entity { Name = "Tom" };
            collection.Insert(entity);
            var id = entity.Id;
With the above an ObjectId is created, but is not passed back to the entity so id = null.
If I remove the SetIgnoreIfNull(true) in the mappings, the entity is still given an ObjectId of null.
> show collections
system.indexes
> db.entities.find()
{ "_id" : ObjectId("51b82adc4f1e762d11438238"), "Name" : "Tom" }
> db.entities.drop()
true
> db.entities.find()
{ "_id" : null, "Name" : "Tom" }
>
I cannot seem to persuade the system that it should create a new ObjectID if the id is null AND get it to return it to me.
 

craiggwilson

unread,
Jun 12, 2013, 11:56:02 AM6/12/13
to mongod...@googlegroups.com
You need to set an IdGenerator.  This generally gets set automatically for ObjectIds during the convention phase (AutoMap), but you have a string instead of an ObjectId.  And because the conventions have already run by the time you set the representation, they don't have the opportunity to pick that up.

There are a couple of things you can do
1) Set the IdGenerator manually when you set the representation.
2) Use a convention that looks for strings with the name Id and set their representation and id generator at the same time.  This would mean you probably would need to call RegisterClassMap at all.  Here is an example one I wrote up a while ago: https://gist.github.com/craiggwilson/5217295

Mark Farmiloe

unread,
Jun 12, 2013, 12:34:36 PM6/12/13
to mongod...@googlegroups.com
Thanks - that was what I was missing. 
 Perhaps the documentation could mention this extra requirement, where it mentions the SetRepresentation ( just for the dummies like me :-) )
 
Reply all
Reply to author
Forward
0 new messages