MongoDB C# Driver - how to store _id as ObjectId but map to string Id property?
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.
In case you want that very same kind of mapping across a whole range of entities without the need to repeat yourself over and over again you might want to use a convention:
public class
StringObjectIdIdGeneratorConventionThatWorks :
ConventionBase, IPostProcessingConvention
{
/// <summary>
/// Applies a post processing modification to the class map.
/// </summary>
/// <param name="classMap">The class map.</param>
public void PostProcess(BsonClassMap classMap)
{
var idMemberMap = classMap.IdMemberMap;
if (idMemberMap == null || idMemberMap.IdGenerator != null)
return;
if (idMemberMap.MemberType == typeof(string))
{
idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance).SetSerializer(new StringSerializer(BsonType.ObjectId));
}
}
}
...and then use it in lieu of all custom mappings:
ConventionPack cp = new ConventionPack();
cp.Add(new StringObjectIdIdGeneratorConventionThatWorks());
ConventionRegistry.Register("TreatAllStringIdsProperly", cp, _ => true);