如何将字符串列表序列化为 objectid 列表

gen*_*ane 3 c# mongodb mongodb-.net-driver

我有一个用这样的类映射的用户集合:

class User
{
  public String Id { get; set; }
  ...
}
Run Code Online (Sandbox Code Playgroud)

Id 属性是文档的标识符;它在 C# 中由一个字符串表示,但在 mongo 中是一个 objectid。以下映射允许确保这一点:

BsonClassMap.RegisterClassMap<User>(cm =>
{
  cm.MapIdProperty(x => x.Id)
    .SetSerializer(new StringSerializer(BsonType.ObjectId))
    .SetIdGenerator(StringObjectIdGenerator.Instance);
  ...
}
Run Code Online (Sandbox Code Playgroud)

我有另一个名为 Book 的集合;每本书都可以由一个或多个作者撰写。

class Book
{
  public String Id { get; set; }
  public String Title { get; set; }
  public IList<String> Authors { get; set; }
  ...
}
Run Code Online (Sandbox Code Playgroud)

Id 属性与 User 集合的相同。我希望每个作者都作为 objectid 而不是 string 存储在 mongo 中:但我不知道该怎么做:我不想定义 autors 属性的序列化程序,而是定义该属性的每个元素的序列化程序。

BsonClassMap.RegisterClassMap<Book>(cm =>
{
  cm.MapIdProperty(x => x.Id)
    .SetSerializer(new StringSerializer(BsonType.ObjectId))
    .SetIdGenerator(StringObjectIdGenerator.Instance);
  // The instruction below is not good and fails, because it maps the collection,
  // not each element of the collection....
  cm.MapMember(x => x.Authors)
    .SetSerializer(new StringSerializer(BsonType.ObjectId));
}
Run Code Online (Sandbox Code Playgroud)

小智 6

注意:这些测试是使用 MongoDB.Driver 2.4.3 执行的

我能够使用 serializer 来完成EnumerableInterfaceImplementerSerializer

在你的情况下,它会是这样的:

BsonClassMap.RegisterClassMap<Book>(cm =>
{
  (...)

  cm.MapMember(x => x.Authors)
    .SetSerializer(
      new EnumerableInterfaceImplementerSerializer<IList<string>, string>(
        new StringSerializer(BsonType.ObjectId)));
}
Run Code Online (Sandbox Code Playgroud)

但是,上面的代码将生成类似于以下内容的文档:

{
   _id: "...",
   Title: "...",
   Authors: {
     _t: "List`1"
     _v: [ObjectId(...), ObjectId(...)] 
   }
}
Run Code Online (Sandbox Code Playgroud)

通过将Book.Authorsfrom更改IListList并配置以下序列化程序:

BsonClassMap.RegisterClassMap<Book>(cm =>
{
  (...)

  cm.MapMember(x => x.Authors)
    .SetSerializer(
      new EnumerableInterfaceImplementerSerializer<List<string>, string>(
        new StringSerializer(BsonType.ObjectId)));
}
Run Code Online (Sandbox Code Playgroud)

我最终得到以下对象:

{
   _id: "...",
   Title: "...",
   Authors: [ObjectId(...), ObjectId(...)]
}
Run Code Online (Sandbox Code Playgroud)