2011-10-08 59 views
16

我有一个类User,我需要在Web服务中使用它们。MongoDB C#:ID序列化最佳模式

那么问题是,如果我试图序列Id那就是BsonObjectId类型,我看到 有一个空的属性时,有一个空的财产,等等...

我写这篇文章的解决方法为什么这是一个很好的解决方案?

public partial class i_User 
{ 
    [BsonId(IdGenerator = typeof(BsonObjectIdGenerator))] 
    [NonSerialized] 
    public BsonObjectId _id; 

    public String Id 
    { 
     get 
     { 
      return this._id.ToString(); 
     } 
    } 
} 

这样,我可以让_IdBsonObjectId,但我在物业Id发送一个字符串表示在网上。

另一种解决方案是StringObjectIdGenerator

public partial class i_User 
{ 
    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))] 
    public String id; 
} 

工作,但被发现的MongoDB会string存储到数据库,而不是ObjectId

为了在像Web服务和/或客户端服务器(Flash + C#)这样的序列化环境中工作,最佳方法是什么?

回答

90

如果我的理解正确,您希望以字符串的形式访问Id属性,但Id保存为MongoDB中的ObjectId。这可以使用BsonRepresentationBsonId来完成。

[BsonId] 
[BsonRepresentation(BsonType.ObjectId)] 
public string Id { get; set; } 

可以找到详细信息here

+3

谢谢!如果可以的话,我会为你投票两次;) – Doobi

+1

你刚刚保存了我的一天 – emreturan

+1

花了2个小时打了一个webapi响应,它不会序列化原始ObjectId。这节省了我大概2个小时 –

6

如果你想用一个类映射到做到这一点 - 这是做它的方式:

BsonClassMap.RegisterClassMap<i_User>(cm => 
{ 
    cm.AutoMap(); 
    cm.SetIdMember(cm.GetMemberMap(x => x.Id) 
    .SetIdGenerator(StringObjectIdGenerator.Instance)); 
}); 
+0

这是一个非常好的方式,POCO保持清洁,这是我最关心的问题。但它实际上将Id存储为Mongo中的字符串。理想的做法是在POCO中有数据库和字符串表示的ObjectId表示。那可能吗? –

+0

不是我所知道的,但我想你可以修改C#驱动程序。 使用ObjectId的目的是它只需要12个字节,并具有时间戳内部版本。为什么不在你的域实体中使用ObjectId? – Lybecker

+1

感谢您快速回答。我通常希望让我的领域层独立于存储层技术。但我猜想一切都是一种折衷。 –

1

也有使用约定一个更通用的方法。 该方法允许您在一个地方为所有模型设置规则。

首先。为ID生成器添加约定

public class IdGeneratorConvention : ConventionBase, IPostProcessingConvention 
{ 
    public void PostProcess(BsonClassMap classMap) 
    { 
     var idMemberMap = classMap.IdMemberMap; 
     if (idMemberMap == null || idMemberMap.IdGenerator != null) 
     { 
      return; 
     } 

     idMemberMap.SetIdGenerator(StringObjectIdGenerator.Instance); 
    } 
} 

第二。注册我们的约定。 Register方法必须在第一个查询之前调用

var conventionPack = new ConventionPack { new IdGeneratorConvention() }; 
ConventionRegistry.Register("Pack", conventionPack, x => true);