RavenDb 在没有反序列化的情况下获取原始 JSON
RavenDb get raw JSON without deserialization
我需要恢复存储在 RavenDb 数据库中的 JSON,知道它的 Id
。这里有什么棘手的,我需要在它反序列化为实际对象之前获取它。这样做的原因是,无论 CLR class 发生什么(它可以彻底改变甚至被删除),我都需要它以与第一次存储时完全相同的形式存在,因为它是对以前状态的审计(它是仅在此时显示,我不会将其用于任何其他用途)。
如果我去
using (var session = Store.OpenSession())
{
return JsonConvert.SerializeObject(session.Load<object>(id));
}
我得到 JSON 反映了基础类型的当前状态,可能是因为它存储在 @metadata.Raven-Clr-Type
中。所以我没有看到已删除的属性,而且我确实看到了首次存储时不存在的空属性。
我想使用 DocumentStore.DatabaseCommands.Get()
来获得 RavenJObject
,但它已在 4.1 中被删除,取而代之的是 Advanced.DocumentQuery
,我无法找到一种方法来做我想做的事使用它。
我也试过像这样使用自己的 AbstractIndexCreationTask
:
class Object_AsJson : AbstractIndexCreationTask<JsonObject>
{
public Configuration_AsJson()
{
Map = configuration => configuration.Select(x => AsJson(x).Select(y => y.Value));
}
}
但是session.Load
不接受TIndexCreator
,在session.Query
中我无法得到Id
,因为我没有对象的任何属性从中查询。
示例:
如果我有这个class:
public class Person
{
string FullName { get; set; }
int Age { get; set; }
}
然后我在 Id
person/A-1
下存储了一个新文档 new Person { FullName = "John Samson", Age = 42 }
,但半年后我决定将此 class 修改为:
public class Person
{
string FirstName { get; set; }
string LastName { get; set; }
int Age { get; set; }
}
现在我想看看 person/A-1
的 JSON 是什么样子,但是尝试加载它会将它映射到 Person
的当前状态,所以我会得到:
{
"FirstName": null,
"LastName": null,
"Age": 42
}
我想得到
{
"FullName": "John Samson",
"Age": 42
}
我可以在 RavenDb Studio GUI 中看到我想要的结果,但我需要在我的代码中获取它才能在我的应用程序中显示它。
有人知道如何处理吗?我们将不胜感激。
来自https://github.com/ravendb/book/blob/v4.0/Ch03/Ch03.md#revisions-and-auditing
“……
审计有点不同。修订告诉您发生了什么变化,而审计通过以下方式告诉您
谁,通常是为了什么。 RavenDB 使用客户端 listeners 支持这种审计,
它可以在文档发生更改时为文档提供额外的上下文。
....
查看如何使用事件处理程序实施审核机制:https://github.com/ravendb/book/blob/v4.0/Ch04/Ch04.md#event-handlers
https://ravendb.net/docs/article-page/4.1/Csharp/migration/client-api/document-store#listeners
使用类似于:
store.OnBeforeStore += (sender, args) =>
{
args.DocumentMetadata["Modified-By"] =
RequestContext.Principal.Identity.GetUserId();
};
好的,所以我终于找到了怎么做,所以我会把它留在这里,供出于某种原因想要这样做的任何人使用。
基本上你只需要创建一个 GetDocumentsCommand
的实例并执行它。就我而言,它看起来像这样:
using (var session = Store.OpenSession(database))
{
var command = new GetDocumentsCommand(id, null, false);
session.Advanced.RequestExecutor.Execute(command, session.Advanced.Context);
var result = command.Result.Results.FirstOrDefault();
var json = result?.ToString(); // At this point you already have your JSON
var jObject = JObject.Parse(json);
jObject.Remove("@metadata"); // If you don't want metadata in your JSON
jObject.Add("Id", id); // Because Id does not appear to be part of JSON
return jObject;
}
我需要恢复存储在 RavenDb 数据库中的 JSON,知道它的 Id
。这里有什么棘手的,我需要在它反序列化为实际对象之前获取它。这样做的原因是,无论 CLR class 发生什么(它可以彻底改变甚至被删除),我都需要它以与第一次存储时完全相同的形式存在,因为它是对以前状态的审计(它是仅在此时显示,我不会将其用于任何其他用途)。
如果我去
using (var session = Store.OpenSession())
{
return JsonConvert.SerializeObject(session.Load<object>(id));
}
我得到 JSON 反映了基础类型的当前状态,可能是因为它存储在 @metadata.Raven-Clr-Type
中。所以我没有看到已删除的属性,而且我确实看到了首次存储时不存在的空属性。
我想使用 DocumentStore.DatabaseCommands.Get()
来获得 RavenJObject
,但它已在 4.1 中被删除,取而代之的是 Advanced.DocumentQuery
,我无法找到一种方法来做我想做的事使用它。
我也试过像这样使用自己的 AbstractIndexCreationTask
:
class Object_AsJson : AbstractIndexCreationTask<JsonObject>
{
public Configuration_AsJson()
{
Map = configuration => configuration.Select(x => AsJson(x).Select(y => y.Value));
}
}
但是session.Load
不接受TIndexCreator
,在session.Query
中我无法得到Id
,因为我没有对象的任何属性从中查询。
示例:
如果我有这个class:
public class Person
{
string FullName { get; set; }
int Age { get; set; }
}
然后我在 Id
person/A-1
下存储了一个新文档 new Person { FullName = "John Samson", Age = 42 }
,但半年后我决定将此 class 修改为:
public class Person
{
string FirstName { get; set; }
string LastName { get; set; }
int Age { get; set; }
}
现在我想看看 person/A-1
的 JSON 是什么样子,但是尝试加载它会将它映射到 Person
的当前状态,所以我会得到:
{
"FirstName": null,
"LastName": null,
"Age": 42
}
我想得到
{
"FullName": "John Samson",
"Age": 42
}
我可以在 RavenDb Studio GUI 中看到我想要的结果,但我需要在我的代码中获取它才能在我的应用程序中显示它。
有人知道如何处理吗?我们将不胜感激。
来自https://github.com/ravendb/book/blob/v4.0/Ch03/Ch03.md#revisions-and-auditing
“……
审计有点不同。修订告诉您发生了什么变化,而审计通过以下方式告诉您
谁,通常是为了什么。 RavenDB 使用客户端 listeners 支持这种审计,
它可以在文档发生更改时为文档提供额外的上下文。
....
查看如何使用事件处理程序实施审核机制:https://github.com/ravendb/book/blob/v4.0/Ch04/Ch04.md#event-handlers
https://ravendb.net/docs/article-page/4.1/Csharp/migration/client-api/document-store#listeners
使用类似于:
store.OnBeforeStore += (sender, args) =>
{
args.DocumentMetadata["Modified-By"] =
RequestContext.Principal.Identity.GetUserId();
};
好的,所以我终于找到了怎么做,所以我会把它留在这里,供出于某种原因想要这样做的任何人使用。
基本上你只需要创建一个 GetDocumentsCommand
的实例并执行它。就我而言,它看起来像这样:
using (var session = Store.OpenSession(database))
{
var command = new GetDocumentsCommand(id, null, false);
session.Advanced.RequestExecutor.Execute(command, session.Advanced.Context);
var result = command.Result.Results.FirstOrDefault();
var json = result?.ToString(); // At this point you already have your JSON
var jObject = JObject.Parse(json);
jObject.Remove("@metadata"); // If you don't want metadata in your JSON
jObject.Add("Id", id); // Because Id does not appear to be part of JSON
return jObject;
}