代码之家  ›  专栏  ›  技术社区  ›  Kieron

MongoDb-U id中嵌套类型的C序列化,以及一些带有私有setter的属性

  •  0
  • Kieron  · 技术社区  · 7 年前

    我需要将一些复杂的文档序列化到MongoDb中,但是我不能更改类定义,因为我无法控制源代码。

    但是,我们需要确保调用方仍然可以使用Linq,所以我们需要将类correclty映射到MongoDb。

    目前我们面临的问题很少:

    1. 这个 _id _表示位于嵌套类上。
    2. 有些具有私有setter的属性需要序列化/值得序列化。

    班级的形状有点像这样:

    public class AggregateType : AggregateBase
    {
        public int IntProperty { get; private set; }
    
        public ComplexObject ComplexObjectProperty { get; private set; }
    }
    

    AggregateBase 看起来像这样:

    abstract public class AggregateBase
    {
        public AggregateDetails Details { get; set; }
    }
    

    最后:

    public class AggregateDetails
    {
        public Guid Id { get; set; }
    
        ...other properties
    }
    

    在基层 ,有一个名为 Details Id Guid . 这个 字段需要映射到 ObjectId MongoDb文档中的字段。

    我需要能够序列化文档,强制使用 Details.Id _身份证 ,并使私有setter也序列化。

    我用一个自定义 JsonContractResolver 没有问题。但事实证明,迁移到MongoDb要复杂一些。

    值得注意的是 AggregateType 类,都有不同的形状。我想找到一种通用的序列化方法,如果可能的话,不必编写很多特定的映射程序,就像我们使用CosmoDb一样。

    除此之外,我们还需要这个解决方案来与MongoDb的Linq查询提供程序一起工作。

    1 回复  |  直到 7 年前
        1
  •  1
  •   cl0ud    7 年前

    我想了一下,我能看到这个工作的唯一方法是创建匹配的类型,作为插入mongodb的POCO。我假设你在用Mongo的C驱动程序。

    public class AggregateTypeDocument : AggregateBaseDocument
    {
       public int IntProperty { get; private set; }
       public ComplexObject ComplexObjectProperty { get; private set; }
    }
    
    abstract public class AggregateBaseDocument
    {
       public AggregateDetailsDocument Details { get; private set; }
    }
    
     public class AggregateDetailsDocument 
     {
        [BsonId]
        public Guid Id { get; private set; }
        ...other properties
     }
    

    现在,您可以使用各种属性将您的类型塑造成更友好的mongo。

    下一步将是在您的存储库(或任何地方)中使用您没有权限访问的类定义来映射类型到新的mongo友好类型。

    我建议 AutoMapper 对于这个或普通的旧实例化。现在你应该可以安全地操作收藏了。请参见下面的automapper示例。

      var normalAggregateType = new AggregateType(); 
    
      var client = new MongoClient("yourconnectionstring");
      var db = client.GetDatabase("mydatabase");
    
      var collection = db.GetCollection<AggregateTypeDocument>("myaggregatetypes");
    
      var mongoAggregateType = Mapper.Map<AggregateTypeDocument>(normalAggregateType);
    
      collection.InsertOne(mongoAggregateType);