简体   繁体   中英

RavenDb get raw JSON without deserialization

I need to recover JSON stored in RavenDb database knowing its Id . What's tricky here, I need to get it before it is deserialized into an actual object. Reason for that is, I need it in exact same form it was first stored in, regardless what happens to the CLR class (it can drastically change or even be removed), because it is an audit of previous state (it's only going to be displayed at this point, I won't use it for anything else).

If I go with

using (var session = Store.OpenSession())
{
    return JsonConvert.SerializeObject(session.Load<object>(id));
}

I get JSON reflecting current state of underlying type, probably because it's stored in @metadata.Raven-Clr-Type . So I don't see removed properties, and I do see empty properties that didn't exist when it was first stored.

I wanted to use DocumentStore.DatabaseCommands.Get() to get RavenJObject , but it is already removed in 4.1 in favor of Advanced.DocumentQuery and I couldn't find a way to do what I want using it.

I've also tried using own AbstractIndexCreationTask like this:

class Object_AsJson : AbstractIndexCreationTask<JsonObject>
{
    public Configuration_AsJson()
    {
        Map = configuration => configuration.Select(x => AsJson(x).Select(y => y.Value));
    }
}

But session.Load doesn't accept TIndexCreator , and in session.Query I can't get Id because I don't have any properties of an object to make query from.


Example:

If I have this class:

public class Person
{
    string FullName { get; set; }
    int Age { get; set; }
}

And I store a new document new Person { FullName = "John Samson", Age = 42 } , under Id person/A-1 , yet half year later I decide to modify this class to:

public class Person
{
    string FirstName { get; set; }
    string LastName { get; set; }
    int Age { get; set; }
}

Now I want to see how JSON of person/A-1 looks like, but an attempt to load it maps it to current state of Person , so I will get:

{
  "FirstName": null,
  "LastName": null,
  "Age": 42
}

And I want to get

{
  "FullName": "John Samson",
  "Age": 42
}

I can see my desired result in RavenDb Studio GUI, but I need to get it in my code to display it in my application.

Does anyone have any idea how to handle that? Just a hint in right direction would be appreciated.

Okay, so I've finally found out how to do it, so I'll leave it here for anyone who, for some reason, wants to do the same.

Basically you just have to make an instance of GetDocumentsCommand and execute it. In my case it looks like this:

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;
}

From https://github.com/ravendb/book/blob/v4.0/Ch03/Ch03.md#revisions-and-auditing

".... Auditing is a bit different. While revisions tell you what changed, auditing tells you by whom and typically what for. RavenDB supports this kind of auditing using client-side listeners , which can provide additional context for the document whenever it's changed. ...."

See how to implement auditing mechanism with Event Handlers : 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

use something similar to:

store.OnBeforeStore += (sender, args) =>
{
args.DocumentMetadata["Modified-By"] =
RequestContext.Principal.Identity.GetUserId();
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM