SQL Server
Supported data types
What each .NET type is stored as in SQL Server, and what each SQL Server type reads back as.
Writing: .NET to the database
The values Create and Update accept, and what each column stores.
| .NET value | Column | Stored as |
|---|---|---|
string |
nvarchar(n), varchar(n), nchar(n), nvarchar(max) |
as written (nchar(n) pads with spaces) |
byte / short / int / long |
tinyint / smallint / int / bigint |
200 / 32000 / 2000000000 / 9000000000000 |
decimal |
decimal(p, s), money |
12345.678901 |
float / double |
real / float |
3.25 / 2.718281828459045 |
bool |
bit |
1 |
Guid |
uniqueidentifier |
6F9619FF-8B86-D011-B42D-00C04FC964FF |
DateTimeOffset |
datetimeoffset |
the moment, in UTC: 22:30 +08:00 is stored as 2026-11-07 14:30:00 +00:00. The same with a hand-written catalog, a preload or none: like PostgreSQL and MySQL, ARX keeps the moment, not the offset (store the offset in a column of its own if the application needs it) |
DateTimeOffset |
datetime2, datetime |
the moment in UTC (2026-11-07 14:30:00), with or without a catalog (SQL Server alone would drop the offset and keep 22:30, eight hours off) |
DateTime |
datetime2, datetime |
as written: 2026-11-07 09:00:00 (datetime rounds to 1/300 of a second) |
DateOnly / TimeOnly |
date / time |
2026-11-07 / 17:45:30 |
byte[], ArxBytea |
varbinary(n), varbinary(max) |
0xCAFE |
ArxJsonB |
nvarchar(max), with CHECK (ISJSON(column) = 1) |
the JSON text (invalid JSON fails the check: ARX3004) |
ArxEntityReference |
the lookup column | the referenced id |
ArxSelectionSetValue |
the set's column | the option's code |
null |
any | NULL |
sbyte / ushort / uint / ulong |
converted to smallint / int / bigint / decimal |
-100 / 65000 / 4000000000 / 18446744073709551615 |
char |
text | X |
a plain enum |
refused (ARX1007) | write (int)value or value.ToString(), or use a selection set, which stores the code its set declares |
DateTime with Kind Utc |
datetimeoffset |
the moment, offset +00:00 |
DateTime with Kind Local |
datetime2, datetimeoffset |
converted to UTC first |
Refused before anything is sent: any other type (ARX1007 UnsupportedValueType: write uri.ToString() rather than a
Uri); arrays (ARX8001: SQL Server has no array columns, so store a list as delimited text, JSON or rows of its own);
NaN and the infinities, and a TimeSpan below zero or of 24 hours or more (ARX4001: time holds a time of day, so
store a duration as a number).
With the column types preloaded (ArxPreLoadMode.DataTypes), a number with a fraction written to a whole-number column is refused before SQL Server (ARX4001 ValueOutOfRange) on a create, an update and a write by a filter, where SQL Server would round or truncate it; a condition in a read (qty < 7.5) isn't refused. A NaN or an infinity written to a declared decimal column is refused the same way.
SQL Server converts some values silently that other databases refuse: "42" into an int, a number into a bit, a
decimal into an int by cutting off the fraction. A preload with column types (ArxPreLoadMode.DataTypes) refuses
those before the database. RealCase2_EveryDataType writes every row of this table and prints what SQL Server stored.
Dates and times
| You have | Use | Column |
|---|---|---|
| A moment (an order was placed) | DateTimeOffset |
datetimeoffset |
| A moment, in a column without an offset | DateTime with Kind Utc |
datetime2 (store UTC, read it back as UTC) |
| A wall-clock time with no zone | DateTime with Kind Unspecified |
datetime2 |
| A calendar date | DateOnly |
date |
| A time of day | TimeOnly |
time |
| A duration | a number (seconds, minutes) | int, bigint |
SQL Server keeps no time zone: datetime2 stores the clock time it is given, and datetimeoffset the clock time and
its offset. ARX writes a DateTimeOffset as its UTC instant and converts a local DateTime to UTC first, so a moment is
never stored hours off. Refused: default(DateTime) (ARX1013: it means "not set",
and SQL Server would store 0001-01-01; use null). ARX never parses a string as a date, but SQL Server converts
one it can read, by the session's date format (01/07/1992 is January 7 under us_english), and refuses one it
can't (ARX4003); with a schema preloaded with data types, ARX refuses every date string first (ARX4004). Parse
dates yourself. Full rules: Data types.
Reading: the database to .NET
What Retrieve and RetrieveMultiple give back for each column.
| SQL Server column | Reads back as | Notes |
|---|---|---|
nvarchar(n), varchar(n), nchar(n), nvarchar(max) |
string |
nchar(n) keeps its padding spaces; "" stays "" |
tinyint / smallint / int / bigint |
byte / short / int / long |
|
decimal(p, s), money |
decimal |
More than 28 significant digits: ARX4001 ValueOutOfRange |
real / float |
float / double |
|
bit |
bool |
|
uniqueidentifier |
Guid |
|
datetimeoffset |
DateTimeOffset |
The clock time and the offset it was stored with |
datetime2, datetime, smalldatetime |
DateTime, Kind Unspecified |
The clock time as stored: SQL Server keeps no zone |
date / time |
DateOnly / TimeOnly |
|
varbinary(n), varbinary(max), rowversion |
byte[] |
|
JSON in nvarchar(max) |
string |
SQL Server 2022 has no JSON type: the text as stored |
sql_variant |
the value's own type | |
An alias type (CREATE TYPE … FROM nvarchar(320)) |
Its base type | |
A declared lookup (.Lookup(...)) |
ArxEntityReference |
Name from the referenced table's .DisplayName(...) |
| A selection set column | Its stored code | entity.GetSelectionSet(column, set, catalog) gives the option |
| NULL | null |
The attribute is present, with a null value |
RealCase1_EveryDataTypeReadBack writes one row of every type with Create and prints each value's .NET type as it
reads back.