MongoDB C#驱动程序 - 如何将_id存储为ObjectId但是映射到字符串Id属性?

Nat*_*ley 12 c# mongodb mongodb-.net-driver

我无法让我的模型将实体的Id属性表示为字符串,但是将其自动生成并由MongoDb在内部表示为本机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);
    }
}
Run Code Online (Sandbox Code Playgroud)

对于// map Id property here上面代码中的行,我尝试了许多不同的配置Id映射的方法,但没有一种方法有效.我尝试过的方法以及调用Save方法时抛出的相关异常是:

// 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);
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我认为这是id处理的标准用例?

Ben*_*nCr 14

这已经改变了,我正在使用最新的1.x驱动程序(Nuget包<package id="mongocsharpdriver" version="2.0.0" targetFramework="net45" />)而不是使用SetRepresentation你设置序列化器.

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));
});
Run Code Online (Sandbox Code Playgroud)


Nat*_*ley 6

找到答案:

cm.IdMemberMap
  .SetRepresentation(BsonType.ObjectId)
  .SetIdGenerator(StringObjectIdGenerator.Instance);
Run Code Online (Sandbox Code Playgroud)

这允许我保存为本机ObjectId,并且仍然将C#中表示的Id表示为字符串.作为一个小问题,必须在查询之前解析id:

public Account GetAccountById(string id)
{
    return _accounts.FindOneById(ObjectId.Parse(id));
}
Run Code Online (Sandbox Code Playgroud)

编辑2015年5月
显然,自从我写这个答案后,驱动程序已经改变了.上面的其他答案对于较新版本是正确的,但如果使用旧版本的驱动程序,仍然可以参考此答案.