MongoDB · Create
Store every kind of value
What each .NET value becomes in MongoDB, in three scenarios: numbers, text and flags; dates and times; and the shapes a document can hold, an embedded document, an array and a picklist with several choices.
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.Application.cs (dbContext.Service, the application's ARX service); SampleCatalog.cs (the tables' ids, keys, lookups and display names); 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 Numbers, text and flags
Numbers keep their width; a decimal stays exact.
Already in scope: service (ArxMongoDbService)
var account = new ArxEntity("account");
account["name"] = "Tailspin Toys";
account["account_number"] = "ACC-M401";
account["employee_count"] = 320;
account["annual_revenue"] = 12_500_000.75m;
account["credit_score"] = 0.87;
account["visits"] = 9_000_000_000L;
account["is_partner"] = true;
account["external_id"] = Guid.Parse("8f14e45f-ceea-467f-a8f9-1d2a3b4c5d6e");
account["industry"] = new ArxSelectionSetValue("Industry", (int)Industry.Retail);
var id = await service.CreateAsync(account);
Console.WriteLine($"created account {id.AsString()}");Check it in the database
Run it in mongosh connected to the database, after the code has run.
db.account.find({ account_number: "ACC-M401" })Expect: employee_count 320, annual_revenue NumberDecimal("12500000.75"), visits NumberLong("9000000000"), external_id UUID("8f14e45f-ceea-467f-a8f9-1d2a3b4c5d6e"), industry 1.
2 Dates and times
Dates are UTC and keep milliseconds; a date alone is midnight UTC.
Already in scope: service (ArxMongoDbService)
var order = new ArxEntity("sales_order");
order["order_number"] = "SO-M401";
order["ordered_at"] = new DateTime(2026, 11, 9, 14, 30, 15, 250, DateTimeKind.Utc);
order["promised_at"] = new DateTimeOffset(2026, 11, 12, 9, 0, 0, TimeSpan.FromHours(1));
order["ship_on"] = new DateOnly(2026, 11, 10);
order["delivery_window_start"] = new TimeOnly(9, 30);
await service.CreateAsync(order);
Console.WriteLine("created order SO-M401");Check it in the database
Run it in mongosh connected to the database, after the code has run.
db.sales_order.find({ order_number: "SO-M401" })Expect: ordered_at ISODate("2026-11-09T14:30:15.250Z"), promised_at ISODate("2026-11-12T08:00:00Z"), ship_on ISODate("2026-11-10T00:00:00Z"), delivery_window_start "09:30:00.0000000".
3 Documents, arrays and picklists
An embedded address, a list of tags, and several preferred channels from a picklist.
Already in scope: service (ArxMongoDbService)
var contact = new ArxEntity("contact");
contact["first_name"] = "Grace";
contact["last_name"] = "Hopper";
contact["email"] = "grace@tailspin.example";
contact["address"] = new ArxJsonB { SerializedValue = "{\"street\":\"1 Navy Way\",\"city\":\"Arlington\",\"country\":\"US\"}" };
contact["tags"] = new[] { "speaker", "vip" };
contact["channels"] = ArxSelectionSetValue.Multiple("ContactChannels", "E", "S");
await service.CreateAsync(contact);
Console.WriteLine("created contact grace@tailspin.example");Check it in the database
Run it in mongosh connected to the database, after the code has run.
db.contact.find({ email: "grace@tailspin.example" })Expect: address { street: "1 Navy Way", city: "Arlington", country: "US" }, tags ["speaker", "vip"], channels ["E", "S"].
Good to know
intis stored as a 32-bit integer,long64-bit,decimalas Decimal128 (exact),doubleas a double.- A
Guidis binary subtype 4 (UUID), abyte[]plain binary. - A
DateTimeis a BSON date, in UTC and to the millisecond: finer ticks are dropped. ADateTimeOffsetkeeps its instant, not its offset; aDateOnlyis midnight UTC; aTimeOnlyis text. ArxJsonBis an embedded document or array; a list or an array is an array.
See also
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
- .NET SDK: .NET SDK 10.0.100 or later 10.0.x (target
net10.0). - Create the project:
Terminal dotnet new console -n ArxSample -f net10.0 cd ArxSample - Install the packages:
Terminal dotnet add package ARX.SDK.MongoDb --version 1.0.0-rc.1 - Database: a MongoDB 7.0, a replica set (tested with 7.0.45, one node) database with the sample schema.
- Configuration: set
ARX_SAMPLES_MONGODBto its connection string. Nothing is hard-coded. - Source code: add the files of the sample application this sample uses (
SampleContext.cs,SampleOutput.cs,SampleContext.Application.cs,SampleCatalog.cs,SampleContext.Direct.cs,MongoDirectHelper.cs), then replaceProgram.csand add the other file below, with the file names shown. - Run it:
Terminal dotnet run - Expected output: below.
The files
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.RealCases;
// 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 RealCase1_EveryDataType().RunAsync(dbContext);
The sample, as it is in the repository.
using ARX.SDK.Models;
using ARX.SDK.MongoDb.Services;
using ARX.SDK.Services;
using static ArxSamples.MongoDb.SampleOutput;
namespace ArxSamples.MongoDb.Operations.Create.RealCases;
/// <summary>
/// What each .NET value becomes in MongoDB, in three scenarios: numbers, text and flags; dates and times; and the
/// shapes a document can hold, an embedded document, an array and a picklist with several choices.
/// </summary>
/// <remarks>
/// <list type="bullet">
/// <item><c>int</c> is stored as a 32-bit integer, <c>long</c> 64-bit, <c>decimal</c> as Decimal128 (exact), <c>double</c> as a double.</item>
/// <item>A <c>Guid</c> is binary subtype 4 (UUID), a <c>byte[]</c> plain binary.</item>
/// <item>A <c>DateTime</c> is a BSON date, in UTC and to the millisecond: finer ticks are dropped. A <c>DateTimeOffset</c>
/// keeps its instant, not its offset; a <c>DateOnly</c> is midnight UTC; a <c>TimeOnly</c> is text.</item>
/// <item><see cref="ArxJsonB"/> is an embedded document or array; a list or an array is an array.</item>
/// </list>
/// </remarks>
public sealed class RealCase1_EveryDataType : ISample
{
public string Name => "create-real-1-every-data-type";
public string Title => "Store every kind of value";
public async Task RunAsync(SampleContext dbContext)
{
await Scenario1_NumbersTextAndFlagsAsync(dbContext.Service);
await Scenario2_DatesAndTimesAsync(dbContext.Service);
await Scenario3_DocumentsArraysAndPicklistsAsync(dbContext.Service);
}
/// <summary>1. Numbers keep their width; a decimal stays exact.</summary>
private static async Task Scenario1_NumbersTextAndFlagsAsync(ArxMongoDbService service)
{
Step("1. Numbers, text and flags");
var account = new ArxEntity("account");
account["name"] = "Tailspin Toys";
account["account_number"] = "ACC-M401";
account["employee_count"] = 320;
account["annual_revenue"] = 12_500_000.75m;
account["credit_score"] = 0.87;
account["visits"] = 9_000_000_000L;
account["is_partner"] = true;
account["external_id"] = Guid.Parse("8f14e45f-ceea-467f-a8f9-1d2a3b4c5d6e");
account["industry"] = new ArxSelectionSetValue("Industry", (int)Industry.Retail);
var id = await service.CreateAsync(account);
Show($"created account {id.AsString()}");
/* ===========================================================
* [DIRECT QUERY CHECK]
* -----------------------------------------------------------
* db.account.find({ account_number: "ACC-M401" })
* -- Expect: employee_count 320, annual_revenue NumberDecimal("12500000.75"), visits NumberLong("9000000000"), external_id UUID("8f14e45f-ceea-467f-a8f9-1d2a3b4c5d6e"), industry 1.
* ===========================================================
*/
}
/// <summary>2. Dates are UTC and keep milliseconds; a date alone is midnight UTC.</summary>
private static async Task Scenario2_DatesAndTimesAsync(ArxMongoDbService service)
{
Step("2. Dates and times");
var order = new ArxEntity("sales_order");
order["order_number"] = "SO-M401";
order["ordered_at"] = new DateTime(2026, 11, 9, 14, 30, 15, 250, DateTimeKind.Utc);
order["promised_at"] = new DateTimeOffset(2026, 11, 12, 9, 0, 0, TimeSpan.FromHours(1));
order["ship_on"] = new DateOnly(2026, 11, 10);
order["delivery_window_start"] = new TimeOnly(9, 30);
await service.CreateAsync(order);
Show("created order SO-M401");
/* ===========================================================
* [DIRECT QUERY CHECK]
* -----------------------------------------------------------
* db.sales_order.find({ order_number: "SO-M401" })
* -- Expect: ordered_at ISODate("2026-11-09T14:30:15.250Z"), promised_at ISODate("2026-11-12T08:00:00Z"), ship_on ISODate("2026-11-10T00:00:00Z"), delivery_window_start "09:30:00.0000000".
* ===========================================================
*/
}
/// <summary>3. An embedded address, a list of tags, and several preferred channels from a picklist.</summary>
private static async Task Scenario3_DocumentsArraysAndPicklistsAsync(ArxMongoDbService service)
{
Step("3. Documents, arrays and picklists");
var contact = new ArxEntity("contact");
contact["first_name"] = "Grace";
contact["last_name"] = "Hopper";
contact["email"] = "grace@tailspin.example";
contact["address"] = new ArxJsonB { SerializedValue = "{\"street\":\"1 Navy Way\",\"city\":\"Arlington\",\"country\":\"US\"}" };
contact["tags"] = new[] { "speaker", "vip" };
contact["channels"] = ArxSelectionSetValue.Multiple("ContactChannels", "E", "S");
await service.CreateAsync(contact);
Show("created contact grace@tailspin.example");
/* ===========================================================
* [DIRECT QUERY CHECK]
* -----------------------------------------------------------
* db.contact.find({ email: "grace@tailspin.example" })
* -- Expect: address { street: "1 Navy Way", city: "Arlington", country: "US" }, tags ["speaker", "vip"], channels ["E", "S"].
* ===========================================================
*/
}
}
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.
> 1. Numbers, text and flags
created account 6af533a5902f556dd2c911a7
> 2. Dates and times
created order SO-M401
> 3. Documents, arrays and picklists
created contact grace@tailspin.example