MongoDB · Create

Create one record and get its id

The smallest create: one document, in four scenarios. The usual way first (the id declared in the schema, an ObjectId ARX makes), then the id declared on the entity, then an id you supply, then a Guid id.

Set up for this page

The scenarios build on the sample application: SampleContext.cs (the dbContext every sample is given); SampleOutput.cs (Step and Show, which print); SampleContext.Direct.cs (dbContext.Direct); MongoDirectHelper.cs (the checks behind dbContext.Direct).

dbContext.Direct is the samples' own checking code on the plain driver, not part of ARX: leave it out of your application.

1 Id in the schema

The usual way: the id declared in the schema; ARX makes an ObjectId and returns it as text.

Already in scope: connectionString (string)

C#
// Declare each collection's id once, at startup. A generated string id is an ObjectId.
var schema = ArxSchemaCatalog.Create()
    .Table("account", ArxIdColumn.Generated<string>("account_id"))
    .Build();

var service = new ArxMongoDbService(connectionString, schema);

var entity = new ArxEntity("account");
entity["name"] = "Northwind Traders";
entity["account_number"] = "ACC-M001";
entity["employee_count"] = 240;

// CreateAsync returns the id of the new document: the ObjectId's 24 hexadecimal characters.
ArxRecordId id = await service.CreateAsync(entity);

Console.WriteLine($"created account {id.AsString()}");

Check it in the database

javascript

Run it in mongosh connected to the database, after the code has run.

db.account.find({ account_number: "ACC-M001" })

Expect: 1 document, _id an ObjectId, name "Northwind Traders", employee_count 240.

2 Id on the entity

The other way: no schema catalog, the id declared on the entity.

Already in scope: connectionString (string)

C#
var service = new ArxMongoDbService(connectionString);

var entity = new ArxEntity("account");
entity.IdColumn = ArxIdColumn.Generated<string>("account_id");
entity["name"] = "Contoso Pharmaceuticals";
entity["account_number"] = "ACC-M002";

await service.CreateAsync(entity);

// The id is also set on the entity.
Console.WriteLine($"created account {entity.RecordId} (read from entity.RecordId)");

Check it in the database

javascript

Run it in mongosh connected to the database, after the code has run.

db.account.find({ account_number: "ACC-M002" })

Expect: 1 document, name "Contoso Pharmaceuticals".

3 An id you supply

An id you supply: a country's code is its id.

Already in scope: connectionString (string)

C#
var schema = ArxSchemaCatalog.Create()
    .Table("country", ArxIdColumn.Supplied<string>("code"))
    .Build();

var service = new ArxMongoDbService(connectionString, schema);

var portugal = new ArxEntity("country");
portugal["code"] = "PT";
portugal["name"] = "Portugal";

ArxRecordId id = await service.CreateAsync(portugal);

Console.WriteLine($"created country {id.AsString()}");

Check it in the database

javascript

Run it in mongosh connected to the database, after the code has run.

db.country.find({ _id: "PT" })

Expect: 1 document, name "Portugal".

4 A Guid id

A Guid id ARX makes (version 7: new ids sort by time).

Already in scope: connectionString (string)

C#
var schema = ArxSchemaCatalog.Create()
    .Table("sales_order", ArxIdColumn.Generated<Guid>("order_id"))
    .Build();

var service = new ArxMongoDbService(connectionString, schema);

var order = new ArxEntity("sales_order");
order["order_number"] = "SO-M001";
order["total"] = 125.50m;

ArxRecordId id = await service.CreateAsync(order);

Console.WriteLine($"created order {id.AsGuid()}");

Check it in the database

javascript

Run it in mongosh connected to the database, after the code has run.

db.sales_order.find({ order_number: "SO-M001" })

Expect: 1 document, _id a UUID, total NumberDecimal("125.50").

Good to know

The declared id is the document's _id. Your code names it by the column you declare (account_id); MongoDB stores it as _id. A collection that doesn't exist yet is made by MongoDB on the first insert.

Run the complete sample

The code above comes from one program, built in a fresh project and run against the database. To run it yourself, here is every file and step.

The program, its files and how to run it

Run it locally

  1. .NET SDK: .NET SDK 10.0.100 or later 10.0.x (target net10.0).
  2. Create the project:
    Terminal
    dotnet new console -n ArxSample -f net10.0
    cd ArxSample
  3. Install the packages:
    Terminal
    dotnet add package ARX.SDK.MongoDb --version 1.0.0-rc.1
  4. Database: a MongoDB 7.0, a replica set (tested with 7.0.45, one node) database with the sample schema.
  5. Configuration: set ARX_SAMPLES_MONGODB to its connection string. Nothing is hard-coded.
  6. Source code: add the files of the sample application this sample uses (SampleContext.cs, SampleOutput.cs, SampleContext.Direct.cs, MongoDirectHelper.cs), then replace Program.cs and add the other file below, with the file names shown.
  7. Run it:
    Terminal
    dotnet run
  8. Expected output: below.

The files

Program.cs

Runs the sample. Generated for this page; it reads the connection string from the environment and first remakes the sample database from sample-schema.json.

using ArxSamples.MongoDb;
using ArxSamples.MongoDb.Operations.Create.Basics;

// The connection string comes from the environment, never from the code (see "Configure the connection").
var connectionString = Environment.GetEnvironmentVariable("ARX_SAMPLES_MONGODB")
    ?? throw new InvalidOperationException("Set the ARX_SAMPLES_MONGODB environment variable to your MongoDB connection string.");

var dbContext = new SampleContext(connectionString);

// Every run starts from the sample data: this deletes and makes again what sample-schema.json lists
// (save the file in the project folder, see Get started).
await dbContext.Direct.ResetAsync();

await new Basic1_CreateOneRecord().RunAsync(dbContext);
Basic1_CreateOneRecord.cs

The sample, as it is in the repository.

using ARX.SDK.MongoDb.Services;
using ARX.SDK.Services;

using static ArxSamples.MongoDb.SampleOutput;

namespace ArxSamples.MongoDb.Operations.Create.Basics;

/// <summary>
/// The smallest create: one document, in four scenarios. The usual way first (the id declared in the schema, an ObjectId
/// ARX makes), then the id declared on the entity, then an id you supply, then a Guid id.
/// </summary>
/// <remarks>
/// The declared id is the document's <c>_id</c>. Your code names it by the column you declare (<c>account_id</c>); MongoDB
/// stores it as <c>_id</c>. A collection that doesn't exist yet is made by MongoDB on the first insert.
/// </remarks>
public sealed class Basic1_CreateOneRecord : ISample
{
    public string Name => "create-basics-1-create-one-record";

    public string Title => "Create one record and get its id";

    public async Task RunAsync(SampleContext dbContext)
    {
        await Scenario1_IdInTheSchemaAsync(dbContext.ConnectionString);

        await Scenario2_IdOnTheEntityAsync(dbContext.ConnectionString);

        await Scenario3_AnIdYouSupplyAsync(dbContext.ConnectionString);

        await Scenario4_AGuidIdAsync(dbContext.ConnectionString);
    }

    /// <summary>1. The usual way: the id declared in the schema; ARX makes an ObjectId and returns it as text.</summary>
    private static async Task Scenario1_IdInTheSchemaAsync(string connectionString)
    {
        Step("1. Id in the schema");

        // Declare each collection's id once, at startup. A generated string id is an ObjectId.
        var schema = ArxSchemaCatalog.Create()
            .Table("account", ArxIdColumn.Generated<string>("account_id"))
            .Build();

        var service = new ArxMongoDbService(connectionString, schema);

        var entity = new ArxEntity("account");
        entity["name"] = "Northwind Traders";
        entity["account_number"] = "ACC-M001";
        entity["employee_count"] = 240;

        // CreateAsync returns the id of the new document: the ObjectId's 24 hexadecimal characters.
        ArxRecordId id = await service.CreateAsync(entity);

        Show($"created account {id.AsString()}");

        /* ===========================================================
         * [DIRECT QUERY CHECK]
         * -----------------------------------------------------------
         * db.account.find({ account_number: "ACC-M001" })
         * -- Expect: 1 document, _id an ObjectId, name "Northwind Traders", employee_count 240.
         * ===========================================================
         */
    }

    /// <summary>2. The other way: no schema catalog, the id declared on the entity.</summary>
    private static async Task Scenario2_IdOnTheEntityAsync(string connectionString)
    {
        Step("2. Id on the entity");

        var service = new ArxMongoDbService(connectionString);

        var entity = new ArxEntity("account");
        entity.IdColumn = ArxIdColumn.Generated<string>("account_id");
        entity["name"] = "Contoso Pharmaceuticals";
        entity["account_number"] = "ACC-M002";

        await service.CreateAsync(entity);

        // The id is also set on the entity.
        Show($"created account {entity.RecordId} (read from entity.RecordId)");

        /* ===========================================================
         * [DIRECT QUERY CHECK]
         * -----------------------------------------------------------
         * db.account.find({ account_number: "ACC-M002" })
         * -- Expect: 1 document, name "Contoso Pharmaceuticals".
         * ===========================================================
         */
    }

    /// <summary>3. An id you supply: a country's code is its id.</summary>
    private static async Task Scenario3_AnIdYouSupplyAsync(string connectionString)
    {
        Step("3. An id you supply");

        var schema = ArxSchemaCatalog.Create()
            .Table("country", ArxIdColumn.Supplied<string>("code"))
            .Build();

        var service = new ArxMongoDbService(connectionString, schema);

        var portugal = new ArxEntity("country");
        portugal["code"] = "PT";
        portugal["name"] = "Portugal";

        ArxRecordId id = await service.CreateAsync(portugal);

        Show($"created country {id.AsString()}");

        /* ===========================================================
         * [DIRECT QUERY CHECK]
         * -----------------------------------------------------------
         * db.country.find({ _id: "PT" })
         * -- Expect: 1 document, name "Portugal".
         * ===========================================================
         */
    }

    /// <summary>4. A Guid id ARX makes (version 7: new ids sort by time).</summary>
    private static async Task Scenario4_AGuidIdAsync(string connectionString)
    {
        Step("4. A Guid id");

        var schema = ArxSchemaCatalog.Create()
            .Table("sales_order", ArxIdColumn.Generated<Guid>("order_id"))
            .Build();

        var service = new ArxMongoDbService(connectionString, schema);

        var order = new ArxEntity("sales_order");
        order["order_number"] = "SO-M001";
        order["total"] = 125.50m;

        ArxRecordId id = await service.CreateAsync(order);

        Show($"created order {id.AsGuid()}");

        /* ===========================================================
         * [DIRECT QUERY CHECK]
         * -----------------------------------------------------------
         * db.sales_order.find({ order_number: "SO-M001" })
         * -- Expect: 1 document, _id a UUID, total NumberDecimal("125.50").
         * ===========================================================
         */
    }
}

Expected output

What dotnet run printed when the sample was verified, on a freshly created sample schema. Ids differ when the tables already hold rows.

Output
  > 1. Id in the schema
      created account 6af53399305d3c89be8228e9
  > 2. Id on the entity
      created account 6af53399305d3c89be8228ea (read from entity.RecordId)
  > 3. An id you supply
      created country PT
  > 4. A Guid id
      created order 01a1cdd1-8e34-764a-b3f7-7ff0c343ec37