更改RavenDB中Id的值

更改RavenDB中Id的值,ravendb,unique-constraint,Ravendb,Unique Constraint,我们有一个名为Organization的实体,在该实体上使用UniqueConstraints捆绑包。我们有一个名为NetName的属性,它是唯一约束和自动生成的Id 因为这是不必要的,所以我们希望使用NetName属性作为Id。因此,我们不需要使用UniqueConstraints来知道它是唯一的,并且在拥有网络名时能够使用Load也能从中获益 在将网络名用作Id之前,我们需要对其进行一些清理,因此我们创建了一个名为TempUniqueNetName的新临时属性,该属性现在包含以下值: &qu

我们有一个名为Organization的实体,在该实体上使用UniqueConstraints捆绑包。我们有一个名为NetName的属性,它是唯一约束和自动生成的Id

因为这是不必要的,所以我们希望使用NetName属性作为Id。因此,我们不需要使用UniqueConstraints来知道它是唯一的,并且在拥有网络名时能够使用Load也能从中获益

在将网络名用作Id之前,我们需要对其进行一些清理,因此我们创建了一个名为TempUniqueNetName的新临时属性,该属性现在包含以下值:

"organizations/"+ CleanupId(this.NetName)
因此,我们现在已经准备好将该值简单地移动到我们的Id。但是我们无法让它工作。我们的问题是,对于下面的PatchRequest,我们在数据库中得到了一个名为Id的新属性,但acctual Id仍然具有相同的值(请参见屏幕截图)。有没有更好(正确)的方法来更改Id的值

实体:

class Organization {
   public string Id { get; set; }

   [UniqueConstraint]
   public string NetName { get; set; }

   public string TempUniqueNetName{ get; set; }
}
我们想做这样的事情:

_documentStore.DatabaseCommands.UpdateByIndex(typeof(Organizations).Name,
            new IndexQuery(),
            new[]
                    {
                        new PatchRequest()
                            {
                                Type = PatchCommandType.Rename,
                                Name = "TempUniqueNetName",
                                Value = new RavenJValue("Id")
                            }
                    });
store.DatabaseCommands.Put(updatedKey, null, document.DataAsJson, newMetadata);
store.DatabaseCommands.Delete(oldKey, null);

我认为您无法通过修补更改文档密钥。它实际上并不是与文档或元数据一起存储的——它会在加载时复制到@id元数据中,让您产生它在那里的错觉,而Raven客户端会将它再次复制到文档中您自己的identity属性中。但实际上,它在底层esent文档存储中是一个单独的值。Raven必须明确知道如何处理这个问题,并为您伪造它

您可以手动将文档从旧id复制到新id并删除旧id,但这可能会很耗时


现在没有一个很好的方法来重命名文档密钥。实际上,应该有一个数据库命令来为单个文档重新设置密钥,并在进行修补时使用单独的PatchCommandType来重新设置密钥。也许这将在将来添加到raven中。

您可以在my github repo中检查PUT-DELETE用法的实现,以更新ID。 它应该是这样的:

_documentStore.DatabaseCommands.UpdateByIndex(typeof(Organizations).Name,
            new IndexQuery(),
            new[]
                    {
                        new PatchRequest()
                            {
                                Type = PatchCommandType.Rename,
                                Name = "TempUniqueNetName",
                                Value = new RavenJValue("Id")
                            }
                    });
store.DatabaseCommands.Put(updatedKey, null, document.DataAsJson, newMetadata);
store.DatabaseCommands.Delete(oldKey, null);

这里还有一些Raven文档:


好的,谢谢你的回答。我们可能会使用您的建议并复制文档。这是一件一次性的事情,所以我不在乎它需要一段时间。希望下一次我们需要它时可以实现:)仅供参考:RavenDB开发人员回答说,他们不会添加此功能,而是“用户可以很容易地将其实现为一对事务性的删除/放置”