PostgreSQL · Retrieve
Every data type, written and read back
What each PostgreSQL type reads back as, in one scenario: a row of data_type_showcase is written with Create and read with Retrieve, and each attribute's .NET type is printed.
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).
1 Written with Create, read with Retrieve
Write one value of each type, read the row, print each attribute's type and value.
Already in scope: service (ArxPgDbService)
var row = new ArxEntity("data_type_showcase");
row["text_value"] = "Read back R641";
row["char_value"] = "AB";
row["smallint_value"] = (short)7;
row["int_value"] = 42;
row["bigint_value"] = 9_000_000_000L;
row["numeric_value"] = 12345.678901m;
row["real_value"] = 1.5f;
row["double_value"] = 2.25d;
row["bool_value"] = true;
row["uuid_value"] = Guid.Parse("6c1b3a6e-7c2d-4c7e-9a51-2a9c6b0e1641");
row["timestamptz_value"] = new DateTime(2026, 4, 1, 9, 30, 0, DateTimeKind.Utc);
row["timestamp_value"] = new DateTime(2026, 4, 1, 9, 30, 0);
row["date_value"] = new DateOnly(2026, 4, 1);
row["time_value"] = new TimeOnly(9, 30);
row["interval_value"] = TimeSpan.FromMinutes(90);
row["bytea_value"] = new byte[] { 1, 2, 3 };
row["jsonb_value"] = new ArxJsonB { SerializedValue = "{\"tier\": \"gold\"}" };
row["text_array"] = new[] { "a", "b" };
row["int_array"] = new[] { 1, 2, 3 };
row["date_array"] = new[] { new DateOnly(2026, 1, 1), new DateOnly(2026, 12, 31) };
row["mood"] = new ArxSelectionSetValue("Mood", "happy");
var id = await service.CreateAsync(row);
var read = await service.RetrieveAsync("data_type_showcase", id) ?? throw new InvalidOperationException("The data_type_showcase record isn't there.");
foreach (var column in new[] { "text_value", "char_value", "smallint_value", "int_value", "bigint_value", "numeric_value", "real_value", "double_value",
"bool_value", "uuid_value", "timestamptz_value", "timestamp_value", "date_value", "time_value", "interval_value", "bytea_value",
"jsonb_value", "text_array", "int_array", "date_array", "mood" })
{
var value = read[column];
var text = value switch
{
ArxJsonB json => json.SerializedValue,
DateTime dateTime => $"{dateTime:yyyy-MM-dd HH:mm} ({dateTime.Kind})",
Array array => "[" + string.Join(", ", array.Cast<object>()) + "]",
_ => value?.ToString()
};
Console.WriteLine($"{column,-18} {value?.GetType().Name,-10} {text}");
}Check it in the database
Run it in any SQL tool connected to the database, after the code has run.
SELECT char_value, date_value, time_value, interval_value, jsonb_value, mood
FROM data_type_showcase
WHERE text_value = 'Read back R641';Expect: 1 row, "AB " (char(3) keeps its padding), 2026-04-01, 09:30:00, 01:30:00, {"tier": "gold"}, happy.
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.PostgreSql --version 1.0.0-rc.1 - Database: a PostgreSQL 16 (tested with 16.15) database with the sample schema.
- Configuration: set
ARX_SAMPLES_POSTGRESQLto 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), 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.
using ArxSamples.PostgreSql;
using ArxSamples.PostgreSql.Operations.Retrieve.RealCases;
// The connection string comes from the environment, never from the code (see "Configure the connection").
var connectionString = Environment.GetEnvironmentVariable("ARX_SAMPLES_POSTGRESQL")
?? throw new InvalidOperationException("Set the ARX_SAMPLES_POSTGRESQL environment variable to your PostgreSQL connection string.");
await new RealCase1_EveryDataTypeReadBack().RunAsync(new SampleContext(connectionString));
The sample, as it is in the repository.
using ARX.SDK.Models;
using ARX.SDK.Services;
using static ArxSamples.PostgreSql.SampleOutput;
namespace ArxSamples.PostgreSql.Operations.Retrieve.RealCases;
/// <summary>
/// What each PostgreSQL type reads back as, in one scenario: a row of data_type_showcase is written with
/// Create and read with Retrieve, and each attribute's .NET type is printed.
/// </summary>
public sealed class RealCase1_EveryDataTypeReadBack : ISample
{
public string Name => "retrieve-real-1-every-data-type-read-back";
public string Title => "Every data type, written and read back";
public async Task RunAsync(SampleContext dbContext)
{
await Scenario1_WriteThenReadEveryTypeAsync(dbContext);
}
/// <summary>1. Write one value of each type, read the row, print each attribute's type and value.</summary>
private static async Task Scenario1_WriteThenReadEveryTypeAsync(SampleContext dbContext)
{
Step("1. Written with Create, read with Retrieve");
var row = new ArxEntity("data_type_showcase");
row["text_value"] = "Read back R641";
row["char_value"] = "AB";
row["smallint_value"] = (short)7;
row["int_value"] = 42;
row["bigint_value"] = 9_000_000_000L;
row["numeric_value"] = 12345.678901m;
row["real_value"] = 1.5f;
row["double_value"] = 2.25d;
row["bool_value"] = true;
row["uuid_value"] = Guid.Parse("6c1b3a6e-7c2d-4c7e-9a51-2a9c6b0e1641");
row["timestamptz_value"] = new DateTime(2026, 4, 1, 9, 30, 0, DateTimeKind.Utc);
row["timestamp_value"] = new DateTime(2026, 4, 1, 9, 30, 0);
row["date_value"] = new DateOnly(2026, 4, 1);
row["time_value"] = new TimeOnly(9, 30);
row["interval_value"] = TimeSpan.FromMinutes(90);
row["bytea_value"] = new byte[] { 1, 2, 3 };
row["jsonb_value"] = new ArxJsonB { SerializedValue = "{\"tier\": \"gold\"}" };
row["text_array"] = new[] { "a", "b" };
row["int_array"] = new[] { 1, 2, 3 };
row["date_array"] = new[] { new DateOnly(2026, 1, 1), new DateOnly(2026, 12, 31) };
row["mood"] = new ArxSelectionSetValue("Mood", "happy");
var id = await dbContext.Service.CreateAsync(row);
var read = await dbContext.Service.RetrieveAsync("data_type_showcase", id) ?? throw new InvalidOperationException("The data_type_showcase record isn't there.");
foreach (var column in new[] { "text_value", "char_value", "smallint_value", "int_value", "bigint_value", "numeric_value", "real_value", "double_value",
"bool_value", "uuid_value", "timestamptz_value", "timestamp_value", "date_value", "time_value", "interval_value", "bytea_value",
"jsonb_value", "text_array", "int_array", "date_array", "mood" })
{
var value = read[column];
var text = value switch
{
ArxJsonB json => json.SerializedValue,
DateTime dateTime => $"{dateTime:yyyy-MM-dd HH:mm} ({dateTime.Kind})",
Array array => "[" + string.Join(", ", array.Cast<object>()) + "]",
_ => value?.ToString()
};
Show($"{column,-18} {value?.GetType().Name,-10} {text}");
}
/* ===========================================================
* [DIRECT QUERY CHECK]
* -----------------------------------------------------------
* SELECT char_value, date_value, time_value, interval_value, jsonb_value, mood
* FROM data_type_showcase
* WHERE text_value = 'Read back R641';
* -- Expect: 1 row, "AB " (char(3) keeps its padding), 2026-04-01, 09:30:00, 01:30:00, {"tier": "gold"}, happy.
* ===========================================================
*/
}
}
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. Written with Create, read with Retrieve
text_value String Read back R641
char_value String AB
smallint_value Int16 7
int_value Int32 42
bigint_value Int64 9000000000
numeric_value Decimal 12345.678901
real_value Single 1.5
double_value Double 2.25
bool_value Boolean True
uuid_value Guid 6c1b3a6e-7c2d-4c7e-9a51-2a9c6b0e1641
timestamptz_value DateTime 2026-04-01 09:30 (Utc)
timestamp_value DateTime 2026-04-01 09:30 (Unspecified)
date_value DateOnly 01/04/2026
time_value TimeOnly 9:30 am
interval_value TimeSpan 01:30:00
bytea_value Byte[] [1, 2, 3]
jsonb_value ArxJsonB {"tier": "gold"}
text_array String[] [a, b]
int_array Int32[] [1, 2, 3]
date_array DateOnly[] [01/01/2026, 31/12/2026]
mood String happy