我可以强制RavenDB允许IDocumentSession.Store()接受具有现有ID的实体吗?

时间:2013-04-25 14:17:03

标签: c# ravendb

我有一个应用程序,我正在从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中,我似乎不允许使用Id属性设置为已获取Id的实体调用IDocumentSession.Save()。更新文档时,根据定义,Id属性将被采用。

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

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

1 个答案:

答案 0 :(得分:1)

我们的想法是不要在User和UserDocument之间进行这样的分离。您希望使用IDocumentSession将User对象存储到RavenDB中 - 它们作为文档存储的事实实际上是您应该关注的实现细节。

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

你应该能够做到两个中的一个:

  1. 使用IDocumentSession.Load(或Query)加载对象,直接更改工作单元并在完成后调用SaveChanges

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

  3. 来做到这一点