1

我有一个应用程序,我正在从 RavenDB 1 升级到 RavenDB 2。该应用程序不直接将其域对象存储在数据库中。相反,域对象在持久化之前被转换为文档对象(读取时反之亦然)。例如,域对象:

public class User {
    public string Id { get; private set; }
    public string Email { get; set; }
    public string PasswordSalt { get; private set; }
    public string PasswordHash { get; private set; }

    public void ChangePassword(string oldPassword, string newPassword) {
        ...
    }
    .
    .
    .
}

以及相应的文档对象(存储在数据库中的内容):

class UserDocument {
    public static UserDocument FromEntity(User user) {
        ...
    }

    public string Id { get; set; }
    public string Email { get; set; }
    public string PasswordSalt { get; set; }
    public string PasswordHash { get; set; }

    public User ToEntity() {
        ...
    }
}

因此,如果我想更改存储在数据库中的用户文档,我通常会加载它,将其转换为相应的域对象,进行更改(例如调用 ChangePassword()),将域对象转换回文档对象并最后调用 IDocumentSession.Store() 和 SaveChanges()。这在 RavenDB 1 中运行良好。

然而,在 RavenDB 2 中,似乎不允许我调用 IDocumentSession.Save() 的实体的 Id 属性设置为采用的 Id。更新文档时,根据定义,将采用 Id 属性。

这个想法似乎是在 RavenDB 2 中我会加载一个对象,更改它,然后调用 SaveChanges() 并且客户端将跟踪已加载的对象并自动将它们发送到服务器。由于我将在代理对象(域对象)中进行所有更改并且不会将原始文档对象留在内存中,因此这对我来说是不可能的。

是否可以将 RavenDB 配置为使用 RavenDB 1 中存在的行为?

4

1 回答 1

1

我们的想法是不要在 User 和 UserDocument 之间进行这种分离。您希望使用 IDocumentSession 将 User 对象存储到 RavenDB 中——就您而言,它们被存储为文档的事实实际上是一个实现细节。

在这方面,RavenDB 1 和 2 之间没有任何真正的区别。

您应该能够执行以下两项之一:

  1. 使用 IDocumentSession.Load(或 Query)加载对象,直接更改 Unit-of-Work 并在完成后调用 SaveChanges

  2. 加载对象,将其更改为另一个对象(使用复制构造函数等),然后将新对象存储在相同的 ID 下。您可以通过调用 session.Store(obj, null, id) 来做到这一点。

于 2013-04-25T18:56:16.157 回答