DataLinq Configuration Files
DataLinq uses JSON configuration files for the CLI and model-generation workflow.
There are two files:
datalinq.jsondatalinq.user.json
The CLI reads the main file first, then looks for a matching .user.json file next to it by replacing the extension. The user file is then merged on top.
For new projects, the easiest way to create both files is:
datalinq config init
What This Config Is For
This config is used by the datalinq CLI.
It is not required for runtime database access if you are instantiating MySqlDatabase<T>, MariaDBDatabase<T>, or SQLiteDatabase<T> directly in application code.
Config Discovery
By default, the CLI looks for datalinq.json in the current working directory.
You can also pass:
- a file path with
-cor--config - a directory path with
-cor--config, in which case DataLinq appendsdatalinq.json
If the main file is:
C:\repo\MyApp\datalinq.json
then the CLI will also look for:
C:\repo\MyApp\datalinq.user.json
Comments in JSON
The config reader strips both:
// single-line comments/* multi-line comments */
That means comment-bearing JSON examples work in practice even though standard JSON does not normally allow comments.
CLI Validation
DataLinq reads config files strictly. Unknown properties and unsupported option values fail fast instead of being ignored, so stale fields such as KeyPlacement are treated as configuration errors.
Run a config-only check when editing shared or user config:
datalinq config validate
datalinq config validate --recursive
This command reads datalinq.json, merges the matching datalinq.user.json when present, and validates the config shape without opening a database connection.
Editor Autocomplete and Validation
DataLinq publishes a JSON Schema for config files:
https://datalinq.org/schemas/datalinq.schema.json
New datalinq config init shared configs include it automatically:
{
"$schema": "https://datalinq.org/schemas/datalinq.schema.json",
"Databases": []
}
You can also write the embedded schema from the CLI. Without --output, the command writes datalinq.schema.json next to the selected config path; use --stdout when you specifically want terminal output.
datalinq config schema
datalinq config schema --update-config
datalinq config schema --output datalinq.schema.json
datalinq config schema --stdout
Editors do not auto-discover a local datalinq.schema.json file. The config file needs one top-level $schema value, such as "$schema": "./datalinq.schema.json". JSON Schema tooling does not support multiple top-level $schema references in one file; if the config already points at the public URL, replace it with the local file reference when you want local schema validation. --update-config adds the local reference only when the file does not already have $schema.
DataLinq accepts comments in config files, but editor behavior depends on the editor. If your editor treats .json files as strict JSON, it may warn about comments even though the CLI accepts them.
Minimal Example: MariaDB or MySQL
{
"$schema": "https://datalinq.org/schemas/datalinq.schema.json",
"Databases": [
{
"Name": "AppDb",
"CsType": "AppDb",
"Namespace": "MyApp.Models",
"ModelDirectory": "Models",
"Connections": [
{
"Type": "MariaDB",
"DataSourceName": "appdb",
"ConnectionString": "Server=localhost;Database=appdb;User ID=app;Password=${env:DATALINQ_APPDB_PASSWORD};"
}
]
}
]
}
Generate models:
datalinq generate models -n AppDb
Generate SQL:
datalinq generate sql -n AppDb -o schema.sql
If you want MySQL instead of MariaDB, change "Type": "MariaDB" to "Type": "MySQL". The password in this example comes from an environment variable so it does not need to be committed to the config file.
Minimal Example: SQLite
{
"$schema": "https://datalinq.org/schemas/datalinq.schema.json",
"Databases": [
{
"Name": "AppDb",
"CsType": "AppDb",
"Namespace": "MyApp.Models",
"ModelDirectory": "Models",
"Connections": [
{
"Type": "SQLite",
"DataSourceName": "app.db",
"ConnectionString": "Data Source=app.db;Cache=Shared;"
}
]
}
]
}
The DataSourceName is also used as the default target file name for SQLite operations unless you override it with --data-source.
Using datalinq.user.json
The normal pattern is:
- keep shared structure in
datalinq.json - keep local connection details or secrets in
datalinq.user.json
Example shared config:
{
"$schema": "https://datalinq.org/schemas/datalinq.schema.json",
"Databases": [
{
"Name": "AppDb",
"CsType": "AppDb",
"Namespace": "MyApp.Models",
"ModelDirectory": "Models"
}
]
}
Example local override:
{
"Databases": [
{
"Name": "AppDb",
"Connections": [
{
"Type": "SQLite",
"DataSourceName": "app.local.db",
"ConnectionString": "Data Source=app.local.db;Cache=Shared;"
}
]
}
]
}
Important merge behavior
Overrides are applied per database name.
In practice, you should treat Connections as a replacing value, not as a deep-merged list. If you override a database entry in datalinq.user.json, include the full Connections array you want to use.
That matters for secrets too. If your shared config does not contain safe-to-commit connection strings, put the real connection details in datalinq.user.json and keep that file out of source control.
Secret References
Connection strings can contain secret references. DataLinq resolves them when a CLI command needs to connect to the database and redacts resolved values from CLI-controlled diagnostics.
Supported references:
${env:NAME}reads an environment variable. This is the best choice for CI.${secret:name}reads a DataLinq local secret set withdatalinq secrets set <name>.${prompt:label}prompts during the current CLI run and keeps the value only in memory.
Examples:
{
"ConnectionString": "Server=localhost;Database=appdb;User ID=app;Password=${env:DATALINQ_APPDB_PASSWORD};"
}
{
"ConnectionString": "Server=localhost;Database=appdb;User ID=app;Password=${secret:datalinq/AppDb/password};"
}
{
"ConnectionString": "${secret:datalinq/AppDb/connection-string}"
}
For inline connection-string values, DataLinq resolves placeholders through the connection-string builder. A password containing a semicolon is escaped as a password value, not spliced into raw connection-string text.
Use local secrets like this:
datalinq secrets set datalinq/AppDb/password
datalinq secrets list
datalinq secrets remove datalinq/AppDb/password
secrets list prints names only. secrets set prompts for the value and confirmation instead of accepting a plaintext command-line argument.
Local DataLinq secrets currently use Windows Credential Manager on Windows. On macOS and Linux, ${secret:...} fails clearly instead of writing a plaintext fallback file; use ${env:...} or ${prompt:...} there for now.
Prompt references are useful for local one-off commands, but they are the wrong choice for unattended automation. In non-interactive runs, ${prompt:...} fails with an error instead of hanging or storing the value.
Database Object Fields
Each item in Databases describes one logical database definition.
Name
Required. Used by CLI selection via-n/--database.CsType
Optional. Defaults toName.Namespace
Optional. Defaults toModels.SourceDirectories
Deprecated. Parsed for compatibility, but active CLI commands read existing model files fromModelDirectoryinstead.ModelDirectory
Optional. The directory where DataLinq writes CLI-generated model declaration files and reads existing model declarations during regeneration.DestinationDirectory
Deprecated compatibility alias forModelDirectory. If both names are present for the same database, they must point to the same path.ModelLayout
Optional. Controls generated model member order. Defaults toPropertyOrder: "Column",PrimaryKeyPlacement: "Top",ForeignKeyPlacement: "Inline", andRelationPlacement: "Bottom".Include
Optional. Limits generation to selected tables or views.UseFileScopedNamespaces
Optional. Defaults tofalse.UseNullableReferenceTypes
Optional. Defaults totrue. When enabled, generated C# uses nullable reference annotations for nullable reference-type columns and starts with#nullable enable. Set this tofalseto keep reference-type annotations out of generated files; DataLinq then emits#nullable disablein those files.CapitalizeNames
Optional. Defaults tofalse.RemoveInterfacePrefix
Optional. Defaults totrue.SeparateTablesAndViews
Optional. Defaults tofalse.Connections
Required by actual CLI usage. If no usable connections exist, commands that need a provider will fail.FileEncoding
Optional. Defaults to UTF-8 without BOM. Supported examples includeUTF8andUTF8BOM.
Connection Fields
Each entry in Connections describes one provider-specific connection.
Type
Required in practice. For the built-in CLI providers, useMySQL,MariaDB, orSQLite.DatabaseName
Optional alias. IfDataSourceNameis missing, this value is used instead.DataSourceName
Required in practice unlessDatabaseNameis present. This is the logical database name, server-side database name, or file name depending on provider.ConnectionString
Required in practice. May contain${env:...},${secret:...}, or${prompt:...}references when used through the CLI.
Generated C# File Headers and Nullable Context
Generated model and database files written by the CLI start with:
// <auto-generated />
// Generated by DataLinq. Supported model class names, property names, relation names, and C# property types may be edited.
// See https://datalinq.org/docs/model-generation.html before changing mapping attributes or using --fresh.
#nullable enable
If UseNullableReferenceTypes is explicitly set to false, the nullable directive is #nullable disable instead.
The nullable directive is intentional. It makes generated files compile with the same nullable interpretation regardless of the consuming project's <Nullable> setting. In practical terms:
- omitted
UseNullableReferenceTypesmeans nullable reference generation is enabled UseNullableReferenceTypes: trueemits nullable reference annotations and#nullable enableUseNullableReferenceTypes: falseopts out and emits#nullable disable
The source generator follows file-level nullable context too. If a model source file contains #nullable enable or #nullable disable, generated source for that model follows the file directive, falling back to the database declaration and then the project setting when no source-level context is available.
The CLI can also add a non-deterministic stamp to generated file headers:
datalinq generate models -n AppDb --stamp-generated-header
That adds the DataLinq CLI version and one UTC generation timestamp shared by the files from that generation run. Leave it off if you want regeneration to avoid timestamp-only source diffs.
Selection Rules in the CLI
- If the config contains more than one database, pass
-n. - If the selected database contains more than one connection type, pass
-p. - If the config path points to a directory, the CLI resolves
datalinq.jsoninside it.
Practical Notes
generate modelswrites generated files toModelDirectory.- When validation or rendering fails before file replacement,
generate modelsreports the issues and does not replace generated output. - Unless
--freshis used,generate modelsreads existing model declarations fromModelDirectoryso supported C# surface edits can be preserved. - For SQLite, the CLI may rewrite the
Data Sourcevalue in the connection string based on the resolved target path.
Summary
datalinq.jsonis the main CLI config file.datalinq.user.jsonis the local override file discovered next to it.- Comments are allowed because the reader strips them before JSON deserialization.
- The safest pattern is to keep shared structure in
datalinq.jsonand local connection details indatalinq.user.json.