我正在尝试为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}}
但在反序列化时似乎并没有连接最后的点。有没有办法实现我的目标?
答案 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,因为没有。的设置。