Skip to content

Use this LLM Friendly Docs as an MCP server for Marten.

The search box in the website knows all the secrets—try it!

For any queries, join our Discord Channel to reach us faster.

JasperFx Logo

JasperFx provides formal support for Marten and other JasperFx libraries. Please check our Support Plans for more details.

Loading Documents by Id ​

Documents can be loaded by id from the IQuerySession interface (and so also IDocumentSession), either one at a time or by an enumerable of id values. The load by id functionality supports GUIDs, integers, long integers, and strings. If the document cannot be found, null is returned.

Loading by Id ​

cs
public async Task LoadById(IDocumentSession session)
{
    var userId = Guid.NewGuid();

    // Load a single document identified by a Guid
    var user = await session.LoadAsync<User>(userId);

    // There's an overload of Load for integers and longs
    var doc = await session.LoadAsync<IntDoc>(15);

    // Another overload for documents identified by strings
    var doc2 = await session.LoadAsync<StringDoc>("Hank");

    // Load multiple documents by a group of id's
    var users = await session.LoadManyAsync<User>(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid());

    var ids = new Guid[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };

    // If you already have an array of id values
    var users2 = await session.LoadManyAsync<User>(ids);
}

snippet source | anchor

Asynchronous Loading ​

cs
public async Task LoadByIdAsync(IQuerySession session, CancellationToken token = default (CancellationToken))
{
    var userId = Guid.NewGuid();

    // Load a single document identified by a Guid
    var user = await session.LoadAsync<User>(userId, token);

    // There's an overload of Load for integers and longs
    var doc = await session.LoadAsync<IntDoc>(15, token);

    // Another overload for documents identified by strings
    var doc2 = await session.LoadAsync<StringDoc>("Hank", token);

    // Load multiple documents by a group of ids
    var users = await session.LoadManyAsync<User>(token, Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid());

    var ids = new Guid[] { Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid() };

    // If you already have an array of id values
    var users2 = await session.LoadManyAsync<User>(token, ids);
}

snippet source | anchor

Batched Loading and the Shared Contract ​

Every LoadManyAsync() overload above is a single round trip, however many ids you pass — Marten sends where id = ANY(:ids) rather than a query per id, so there is no parameter ceiling to work around and no benefit to chunking the list yourself.

That also holds when you reach Marten through IDocumentReadOperations, the store-agnostic read contract shared with the other Critter Stack stores:

cs
public static async Task<IReadOnlyList<Reservation>> LoadAll(
    JasperFx.Events.Documents.IDocumentReadOperations session,
    IEnumerable<Guid> ids,
    CancellationToken token)
{
    // Store-agnostic, and on Marten this is a single round trip.
    // Ids with no document are left out, and a repeated id comes back once.
    return await session.LoadManyAsync<Reservation>(ids, token);
}

snippet source | anchor

Ids with no document are left out of the result, a repeated id yields its document once, and the order of the returned list is not part of the contract — sort it yourself if you need one.

TIP

The contract ships a default implementation that loads one document per round trip, and Marten overrides it. If you are writing store-agnostic code, the semantics above are the same on every store; only the round-trip count differs.

Released under the MIT License.