我一直在为一个域建模几天,并没有考虑到持久性,而是专注于域逻辑。现在我已经准备好保留我的域对象,其中一些包含IEnumerable子实体。使用RavenDb,持久性是“容易的”,但是当再次加载我的对象时,所有的IEnumerables都是空的。
我意识到这是因为他们根本没有任何属性设置器,而是使用列表作为支持字段。域聚合根的用户可以通过公共方法添加子实体,而不是直接在集合上添加。
private readonly List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts { get { return _veryImportantParts; } }
添加方法,没什么特别的......
public void AddVeryImportantPart(VeryImportantPart part)
{
// some logic...
_veryImportantParts.Add(part);
}
我可以通过在我的所有IEnumerables上添加一个私有/受保护的setter来修复此问题,但它看起来......好吧......不是超级性感。
private List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts
{
get { return _veryImportantParts; }
protected set { _veryImportantParts = value.ToList(); }
}
现在RavenDb json序列化器会再次加载我的对象,但是我很好奇是否有更简洁的方法呢?
我一直在使用 JsonContractResolver ,但尚未找到解决方案......
答案 0 :(得分:0)
您需要来保留私人支持字段吗?自动财产通常会这样做。
public IList<VeryImportantPart> VeryImportantParts { get; protected set; }
执行此操作时,您可能希望在构造函数中初始化列表:
VeryImportantParts = new List<VeryImportantPart>();
当然,这是可选的,但它允许您创建一个新类,并在它保持之前立即开始添加到列表中。当Raven反序列化一个类时,它将使用setter覆盖默认的空白列表,因此这只会对第一个商店有所帮助。
您肯定无法使用readonly
字段,因为在反序列化期间无法替换它。它可能可以编写一个合同解析器或转换器来填充现有列表而不是创建一个新列表,但这似乎是一个相当复杂的解决方案。
使用自动属性无论如何都可以增加代码的清晰度 - 因为无论是使用字段还是属性都不会产生混淆。
答案 1 :(得分:0)
我认为我找到了这个问题的根本原因,这可能是因为我的许多实体是使用以下方式创建的:
protected MyClass(Guid id, string name, string description) : this()
{ .... }
public static MyClass Create(string name, string description)
{
return new MyClass(Guid.NewGuid(), name, description);
}
反序列化时,RavenDb / Json.net无法以正确的方式重建我的实体......
更改为使用公共构造函数完全不同。