Query for Raw JSON
Marten stores documents as JSON, and sometimes it might be valuable to access the raw JSON representation of the stored documents. To that end, the IQuerySession.Json property gives you access to several helper methods to load JSON strings.
[Fact]
public async Task when_find_then_a_json_should_be_returned()
{
var issue = new Issue { Title = "Issue 2" };
theSession.Store(issue);
await theSession.SaveChangesAsync();
var json = await theSession.Json.FindByIdAsync<Issue>(issue.Id);
json.ShouldBe($"{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"BugId\": null, \"Title\": \"Issue 2\", \"Number\": 0, \"Status\": null, \"AssigneeId\": null, \"ReporterId\": null}}");
}[Fact]
public async Task when_find_then_a_json_should_be_returned()
{
var issue = new Issue { Title = "Issue 2" };
theSession.Store(issue);
await theSession.SaveChangesAsync();
var json = await theSession.Json.FindByIdAsync<Issue>(issue.Id);
json.ShouldBe($"{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"BugId\": null, \"Title\": \"Issue 2\", \"Number\": 0, \"Status\": null, \"AssigneeId\": null, \"ReporterId\": null}}");
}Marten supplies the following functionality to retrieve the raw JSON strings:
[Fact]
public async Task when_get_json_then_raw_json_should_be_returned()
{
// Its sibling already does this. Both tests store an "Issue 1" and then call
// ToJsonSingle(), which requires exactly one match, so whichever runs second
// fails without a reset.
await theStore.Advanced.ResetAllData();
var issue = new Issue { Title = "Issue 1" };
theSession.Store(issue);
await theSession.SaveChangesAsync();
var json = await theSession.Query<Issue>().Where(x => x.Title == "Issue 1").ToJsonArray();
json.ShouldNotBeNull();
json = await theSession.Query<Issue>().ToJsonFirst();
json = await theSession.Query<Issue>().ToJsonFirstOrDefault();
json = await theSession.Query<Issue>().ToJsonSingle();
json = await theSession.Query<Issue>().ToJsonSingleOrDefault();
}And the asynchronous version:
[Fact]
public async Task when_get_json_then_raw_json_should_be_returned_async()
{
await theStore.Advanced.ResetAllData();
var issue = new Issue { Title = "Issue 1" };
theSession.Store(issue);
await theSession.SaveChangesAsync();
var json = await theSession.Query<Issue>().Where(x => x.Title == "Issue 1").ToJsonArray();
json.ShouldNotBeNull();
json = await theSession.Query<Issue>().ToJsonFirst();
json = await theSession.Query<Issue>().ToJsonFirstOrDefault();
json = await theSession.Query<Issue>().ToJsonSingle();
json = await theSession.Query<Issue>().ToJsonSingleOrDefault();
}Using AsJson() with Select() Transforms
Marten has the ability to combine the AsJson() mechanics to the result of a Select() transform:
TIP
When a Select() projection is a "simple" flat member-access transform, Marten pushes the whole reshaping down into a single jsonb_build_object(...) SQL expression instead of deserializing the full document on the client, which is what makes the raw JSON results below possible without an extra serialization round trip. See Projection Operators for the details and its limitations.
var json = await theSession
.Query<User>()
.OrderBy(x => x.FirstName)
// Transform the User class to a different type
.Select(x => new UserName { Name = x.FirstName })
.ToJsonFirst();
json.ShouldBe("{\"Name\": \"Bill\"}");And another example, but this time transforming to an anonymous type:
(await theSession
.Query<User>()
.OrderBy(x => x.FirstName)
// Transform to an anonymous type
.Select(x => new {Name = x.FirstName})
// Select only the raw JSON
.ToJsonFirstOrDefault())
.ShouldBe("{\"Name\": \"Bill\"}");
