Added in Marten v0.6 is the ability to retrieve just the raw JSON string for a document. The point is to be able to fetch the raw JSON from the database for a document and immediately stream that data to a web client without having to take the performance hit of deserializing and serializing the object to and from JSON.
As of v0.6, Marten supplies the IQuerySession/IDocumentSession.FindById<T>()
mechanism as shown below:
[Fact]
public void when_find_then_a_json_should_be_returned()
{
var issue = new Issue { Title = "Issue 1" };
theSession.Store(issue);
theSession.SaveChanges();
var json = theSession.Json.FindById<Issue>(issue.Id);
json.ShouldBe($"{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"BugId\": null, \"Title\": \"Issue 1\", \"Number\": 0, \"AssigneeId\": null, \"ReporterId\": null}}");
}
There is also an asynchronous version:
[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().ConfigureAwait(false);
var json = await theSession.Json.FindByIdAsync<Issue>(issue.Id).ConfigureAwait(false);
json.ShouldBe($"{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"BugId\": null, \"Title\": \"Issue 2\", \"Number\": 0, \"AssigneeId\": null, \"ReporterId\": null}}");
}
As of v0.9, Marten supplies the following functionality to retrieve the raw JSON strings:
//[Fact]
public void when_get_json_then_raw_json_should_be_returned()
{
var issue = new Issue { Title = "Issue 1" };
theSession.Store(issue);
theSession.SaveChanges();
var json = theSession.Query<Issue>().Where(x => x.Title == "Issue 1").ToJsonArray();
json.ShouldBe($"[{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"Title\": \"Issue 1\", \"AssigneeId\": null, \"ReporterId\": null}}]");
json = theSession.Query<Issue>().AsJson().First();
json.ShouldBe($"{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"Title\": \"Issue 1\", \"AssigneeId\": null, \"ReporterId\": null}}");
json = theSession.Query<Issue>().AsJson().FirstOrDefault();
json = theSession.Query<Issue>().AsJson().Single();
json = theSession.Query<Issue>().AsJson().SingleOrDefault();
}
And the asynchronous version:
//[Fact]
public async Task when_get_json_then_raw_json_should_be_returned_async()
{
var issue = new Issue { Title = "Issue 1" };
theSession.Store(issue);
theSession.SaveChanges();
var json = await theSession.Query<Issue>().Where(x => x.Title == "Issue 1").ToJsonArrayAsync().ConfigureAwait(false);
json.ShouldBe($"[{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"Title\": \"Issue 1\", \"AssigneeId\": null, \"ReporterId\": null}}]");
json = await theSession.Query<Issue>().AsJson().FirstAsync().ConfigureAwait(false);
json.ShouldBe($"{{\"Id\": \"{issue.Id}\", \"Tags\": null, \"Title\": \"Issue 1\", \"AssigneeId\": null, \"ReporterId\": null}}");
json = await theSession.Query<Issue>().AsJson().FirstOrDefaultAsync().ConfigureAwait(false);
json = await theSession.Query<Issue>().AsJson().SingleAsync().ConfigureAwait(false);
json = await theSession.Query<Issue>().AsJson().SingleOrDefaultAsync().ConfigureAwait(false);
}
Using AsJson() with Select() Transforms
New for Marten v0.9.1 is the ability to combine the AsJson()
mechanics to the result of a Select()
transform:
theSession
.Query<User>()
.OrderBy(x => x.FirstName)
// Transform the User class to a different type
.Select(x => new UserName { Name = x.FirstName })
.AsJson()
.First()
.ShouldBe("{\"Name\": \"Bill\"}");
And another example, but this time transforming to an anonymous type:
theSession
.Query<User>()
.OrderBy(x => x.FirstName)
// Transform to an anonymous type
.Select(x => new { Name = x.FirstName })
// Select only the raw JSON
.AsJson()
.FirstOrDefault()
.ShouldBe("{\"Name\": \"Bill\"}");