在MongoDB中反序列化聚合根ID

时间:2016-02-04 01:54:40

标签: c# json mongodb

我正在尝试为MongoDB中的Aggregate Roots实现一个存储库层。当我从商店检索实体时,我无法完全反序列化我的实体。一般来说,这些实体没有默认构造函数,并使用GUID作为其实体ID。 ID字段为Id

// Example Aggregate Root
public class MyAggregateRoot : Entity<Guid> {

    // New Constructor
    public MyAggregateRoot(string someInitialState) 
        : base(Guid.NewGuid()) { }

    // Reinitializing Constructor
    public MyAggregateRoot(Guid id, string someInitialState) 
        : base(id) { }

}

public abstract class Entity<T> {

    protected Entity(T id) {
        Id = id;
    }

    public T Id { get; }

}

我正在检索这样的实体:

public MyAggregateRoot GetById(Guid id) {

    var collections = _db.GetCollection<Account>("accounts");
    var entity = collections.Find(a => a.Id == id).ToList().FirstOrDefault();

    return entity;

}

我遇到的问题是,在检索实体时,除Id字段外,所有内容似乎都正确反序列化,00000000-0000-0000-0000-000000000000字段的默认值为Id

当我在控制台中查找记录时,我发现_id字段未直接序列化,而是序列化为{ "_id" : BinData(3,"jac2kSM6aU2xXnS0DXNkJA=="), "SomeInitialState" : "My Incredibly Significant Value" }

Id

我知道Mongo能够将正确的ID与collections.Find(a => a.Id == id).ToList()相关联,因为以下是lambda:

{{1}}

但在反序列化时似乎并没有连接最后的点。有没有办法实现我的目标?

2 个答案:

答案 0 :(得分:1)

问题是Mongo序列化程序无法处理具有private readonly setter的属性。反序列化对象时,只是使用这些字段的默认值

我更改Id上的Entity<T>属性以使用private setter后,该值已正确序列化。

public abstract class Entity<T> {

    protected Entity(T id) {
        Id = id;
    }

    public T Id { get; private set; }

}

答案 1 :(得分:1)

虽然你自己的答案是正确的,Mongo无法处理readonly属性,但根本原因有点不同。

$arr = array(); $arr['obj1'] = $object1; $arr['obj2'] = $object2; $arr['obj3'] = $object3; 只有属性根本没有setter 。相反,以下

get

等同于以下前C#6代码

public T Id { get; }
protected Entity(T id) { Id = id; }

其中编译器自动将对属性的引用替换为构造函数

中的字段

所以问题是MongoDB找不到属性的任何 setter,因为没有。的设置。