I'm having trouble getting my model to represent an entity's Id
property as a string but have it auto-generated and represented internally by MongoDb as a native ObjectId
.
class Account
{
public string Id { get; set; }
...
}
class AccountStore
{
static AccountStore()
{
BsonClassMap.RegisterClassMap<Account>(cm =>
{
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
// map Id property here
});
}
public void Save(Account account)
{
_accounts.Save(account);
}
}
For the line // map Id property here
in the above code, I've tried numerous different ways of configuring the Id mapping and none have worked. The ways I have tried, and the associated exceptions that are thrown when I call the Save
method, are:
// Exception: No IdGenerator found.
cm.IdMemberMap
.SetRepresentation(BsonType.ObjectId);
// Exception: No IdGenerator found.
cm.IdMemberMap
.SetRepresentation(BsonType.String);
// Exception: Unable to cast object of type 'MongoDB.Bson.ObjectId' to type 'System.String'.
cm.IdMemberMap
.SetRepresentation(BsonType.ObjectId)
.SetIdGenerator(ObjectIdGenerator.Instance);
// Exception: Unable to cast object of type 'MongoDB.Bson.ObjectId' to type 'System.String'.
cm.IdMemberMap
.SetRepresentation(BsonType.String)
.SetIdGenerator(ObjectIdGenerator.Instance);
// Exception: Unable to cast object of type 'MongoDB.Bson.ObjectId' to type 'System.String'.
cm.IdMemberMap
.SetIdGenerator(ObjectIdGenerator.Instance);
What am I doing wrong? I thought this was a standard use case for id handling?
By developing with C# and MongoDB together one opens up a world of possibilities. Console, window, and web applications are all possible. As are cross-platform mobile applications using the Xamarin framework.
The official MongoDB Node. js driver allows Node. js applications to connect to MongoDB and work with data. The driver features an asynchronous API which allows you to interact with MongoDB using Promises or via traditional callbacks.
MongoDB allows teams to choose their cloud provider of choice while providing database management that streamlines every aspect of database administration. It's easy to get started with MongoDB Atlas, and it's free.
This has changed, I'm using the latest 1.x driver (Nuget package <package id="mongocsharpdriver" version="2.0.0" targetFramework="net45" />
) and instead of using SetRepresentation
you set the serialiser.
public class RegistrationAttempt
{
public string AttemptId { get; set; }
}
BsonClassMap.RegisterClassMap<RegistrationAttempt>(cm =>
{
cm.AutoMap();
cm.MapIdProperty(c => c.AttemptId)
.SetIdGenerator(StringObjectIdGenerator.Instance)
.SetSerializer(new StringSerializer(BsonType.ObjectId));
});
Found the answer:
cm.IdMemberMap
.SetRepresentation(BsonType.ObjectId)
.SetIdGenerator(StringObjectIdGenerator.Instance);
This allows me to save as a native ObjectId and still have the Id represented in C# as a string. As a small gotcha, the id must be parsed before being queried upon:
public Account GetAccountById(string id)
{
return _accounts.FindOneById(ObjectId.Parse(id));
}
Edit May 2015
Apparently the driver has changed since I wrote this answer. The other answer above is correct for newer versions, but this answer can still be referred to if using a legacy version of the driver.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With