Common Column Types
One of the key design goals of the Cratis Application Model support for Entity Framework is to make it easy to support different databases for an application.
If you're willing to hand-roll Entity Framework migrations, you can leverage the extension methods that will give you a single migration but support different database types resolved at runtime.
Available Column Extension Methods
The following table shows all the column extension methods available in the Cratis Application Model:
| Extension Method | Description | Supported Types | Parameters |
|---|---|---|---|
StringColumn() |
Creates a string column with appropriate database-specific type (VARCHAR/NVARCHAR/TEXT) | string | maxLength (int?, optional), nullable (bool, default: true) |
NumberColumn<T>() |
Creates a numeric column with appropriate database-specific type for any numeric type | char, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal | nullable (bool, default: true) |
BoolColumn() |
Creates a boolean column with appropriate database-specific type (BOOLEAN/BIT/INTEGER) | bool | nullable (bool, default: true) |
AutoIncrementColumn() |
Creates an auto-incrementing integer column with appropriate database-specific annotations | int | None (always non-nullable) |
GuidColumn() |
Creates a GUID/UUID column with appropriate database-specific type (UUID/UNIQUEIDENTIFIER/TEXT) | Guid | nullable (bool, default: true) |
DateTimeOffsetColumn() |
Creates a DateTimeOffset column with appropriate database-specific type (TIMESTAMPTZ/DATETIMEOFFSET/TEXT) | DateTimeOffset | nullable (bool, default: true) |
JsonColumn<T>() |
Creates a JSON column with appropriate database-specific type (jsonb/nvarchar(max)/text) | Any type | None (always non-nullable) |
Database-Specific Type Mappings
The extension methods automatically select the appropriate SQL type based on the database provider:
String Types
- PostgreSQL:
VARCHAR(n)for limited length,TEXTfor unlimited - SQL Server:
NVARCHAR(n)for limited length,NVARCHAR(MAX)for unlimited - SQLite:
TEXT
Numeric Types
The NumberColumn<T>() method supports all .NET numeric types and maps them appropriately:
- PostgreSQL: SMALLINT, INTEGER, BIGINT, NUMERIC, REAL, DOUBLE PRECISION, DECIMAL
- SQL Server: TINYINT, SMALLINT, INT, BIGINT, DECIMAL, REAL, FLOAT
- SQLite: INTEGER, REAL (simplified type system)
Boolean Types
- PostgreSQL:
BOOLEAN - SQL Server:
BIT - SQLite:
INTEGER
GUID/UUID Types
- PostgreSQL:
UUID - SQL Server:
UNIQUEIDENTIFIER - SQLite:
TEXT
DateTime Types
- PostgreSQL:
TIMESTAMPTZ - SQL Server:
DATETIMEOFFSET - SQLite:
TEXT
JSON Types
- PostgreSQL:
jsonb - SQL Server:
nvarchar(max) - SQLite:
text
Note: Read more about JSON in this article
Usage Examples
Auto Incremental Primary Key
Auto incremental primary keys are very common but implemented in different ways with different annotations for them to
actual auto increment. The .AutoIncrementColumn() extension method for the ColumnsBuilder gives you a way to configure
it once.
[DbContext(typeof(EventLogDbContext))]
[Migration($"EventLog_{nameof(v1_0_0)}")]
public class v1_0_0 : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "EventLog",
columns: table => new
{
SequenceNumber = table.AutoIncrementColumn(migrationBuilder), // Creates an auto increment column
/*
Other columns...
*/
},
constraints: table => table.PrimaryKey("PK_EventLog", x => x.SequenceNumber));
}
}
String Columns with Length Limits
columns: table => new
{
Name = table.StringColumn(migrationBuilder, maxLength: 100), // VARCHAR(100)/NVARCHAR(100)
Description = table.StringColumn(migrationBuilder), // TEXT/NVARCHAR(MAX)
}
Numeric Columns
columns: table => new
{
Count = table.NumberColumn<int>(migrationBuilder), // INTEGER/INT
Price = table.NumberColumn<decimal>(migrationBuilder), // DECIMAL
Score = table.NumberColumn<double>(migrationBuilder), // DOUBLE PRECISION/FLOAT/REAL
}
Other Column Types
columns: table => new
{
IsActive = table.BoolColumn(migrationBuilder), // BOOLEAN/BIT/INTEGER
Id = table.GuidColumn(migrationBuilder, nullable: false), // UUID/UNIQUEIDENTIFIER/TEXT
CreatedAt = table.DateTimeOffsetColumn(migrationBuilder), // TIMESTAMPTZ/DATETIMEOFFSET/TEXT
Metadata = table.JsonColumn<Dictionary<string, object>>(migrationBuilder), // jsonb/nvarchar(max)/text
}