在RavenDb中使用私有支持字段反序列化IEnumerable

在RavenDb中使用私有支持字段反序列化IEnumerable,ravendb,Ravendb,我已经为一个域建模了几天了,根本没有考虑持久性,而是专注于域逻辑。现在,我准备持久化我的域对象,其中一些包含IEnumerable子实体。使用RavenDb,持久性“很容易”,但是当再次加载我的对象时,所有IEnumerable都是空的 我意识到这是因为它们根本没有任何属性设置器,而是使用列表作为支持字段。域聚合根目录的用户可以通过公共方法而不是直接在集合上添加子实体 private readonly List<VeryImportantPart> _veryImportantPar

我已经为一个域建模了几天了,根本没有考虑持久性,而是专注于域逻辑。现在,我准备持久化我的域对象,其中一些包含IEnumerable子实体。使用RavenDb,持久性“很容易”,但是当再次加载我的对象时,所有IEnumerable都是空的

我意识到这是因为它们根本没有任何属性设置器,而是使用列表作为支持字段。域聚合根目录的用户可以通过公共方法而不是直接在集合上添加子实体

private readonly List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts { get { return _veryImportantParts; } }
我可以通过在我的所有IEnumerables上添加一个私有/受保护的setter来解决这个问题,但它看起来。。。好。。。不是超级性感

private List<VeryImportantPart> _veryImportantParts;
public IEnumerable<VeryImportantPart> VeryImportantParts
{
    get { return _veryImportantParts; }
    protected set { _veryImportantParts = value.ToList(); }
}
private List\u非常重要的部件;
公共i数不清的非常重要的部件
{
获取{return\u veryiimportantparts;}
受保护集{u veryiimportantparts=value.ToList();}
}
现在,RavendBJSON序列化程序将再次在加载时填充我的对象,但我很好奇,是否有更干净的方法来实现这一点

我一直在摆弄JsonContractResolver,但还没有找到解决方案…

您需要保留一个私人支持字段吗?通常,自动属性就可以了

public IList<VeryImportantPart> VeryImportantParts { get; protected set; }
public IList VeryImportantParts{get;protected set;}
执行此操作时,您可能希望在构造函数中初始化列表:

VeryImportantParts = new List<VeryImportantPart>();
veryiimportantparts=newlist();
当然,这是可选的,但它允许您创建一个新类,并在持久化之前立即开始添加到列表中。当Raven反序列化一个类时,它将使用setter覆盖默认的空白列表,因此这对第一个存储区很有帮助

您当然不能使用
只读
字段,因为在反序列化过程中无法替换该字段。也许可以编写一个契约解析器或转换器来填充现有列表,而不是创建一个新列表,但这似乎是一个相当复杂的解决方案


无论怎样,使用自动属性都可以增加代码的清晰度,因为无论是使用字段还是属性,都不太容易混淆。

我想我已经找到了这个问题的根本原因,这可能是因为我的许多实体都是使用以下方法创建的:

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无法以正确的方式重建实体


改用公共构造函数带来了所有的不同。

好吧,我真的不想将IList公开给这个域对象的“用户”来做它喜欢做的事情,而是使用一个更具意图的界面,正如Jimmy Bogard在这里描述的那样是的,这有时是需要的。不幸的是,它很难在一种形式中揭示,但在另一种形式中反序列化。您如何描述添加受保护或私有setter是一种解决方案。另一种方法是使用一个自动私有属性,并使用一个方法显示,例如
public IEnumerable GetVeryImportantParts()
,您还可以尝试添加一个私有或受保护的无参数构造函数。
protected MyClass(Guid id, string name, string description) : this()
{ .... }

public static MyClass Create(string name, string description)
{
    return new MyClass(Guid.NewGuid(), name, description);
}