{"id":20668689,"url":"https://github.com/avanade/dbex","last_synced_at":"2025-09-12T06:41:56.412Z","repository":{"id":40376224,"uuid":"429340972","full_name":"Avanade/DbEx","owner":"Avanade","description":"DbEx provides database extensions for DbUp-inspired database migrations.","archived":false,"fork":false,"pushed_at":"2025-02-01T23:14:29.000Z","size":432,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-15T17:53:55.243Z","etag":null,"topics":["ado-net","database","dbup","sql","sql-server"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Avanade.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-18T07:49:27.000Z","updated_at":"2025-02-22T01:58:52.000Z","dependencies_parsed_at":"2024-01-16T03:37:32.768Z","dependency_job_id":"2193e382-9a5b-4f2e-ada2-1af928f5f6d9","html_url":"https://github.com/Avanade/DbEx","commit_stats":{"total_commits":36,"total_committers":4,"mean_commits":9.0,"dds":0.25,"last_synced_commit":"32002ac1542d3045a36b665f4fb3feb779b67abd"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":"Avanade/avanade-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Avanade%2FDbEx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Avanade%2FDbEx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Avanade%2FDbEx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Avanade%2FDbEx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Avanade","download_url":"https://codeload.github.com/Avanade/DbEx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249758678,"owners_count":21321576,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ado-net","database","dbup","sql","sql-server"],"created_at":"2024-11-16T20:10:53.393Z","updated_at":"2025-04-19T18:09:08.328Z","avatar_url":"https://github.com/Avanade.png","language":"C#","readme":"\u003cbr/\u003e\n\n![Logo](./images/Logo256x256.png \"DbEx\")\n\n\u003cbr/\u003e\n\n## Introduction\n\n_DbEx_ provides database extensions for [DbUp-inspired](#DbUp-inspired) database migrations.\n\n\u003cbr/\u003e\n\n## Status\n\nThe build status is [![CI](https://github.com/Avanade/DbEx/workflows/CI/badge.svg)](https://github.com/Avanade/DbEx/actions?query=workflow%3ACI) with the NuGet package status as follows, including links to the underlying source code and documentation:\n\nPackage | Status | Source \u0026 documentation\n-|-|-\n`DbEx` | [![NuGet version](https://badge.fury.io/nu/DbEx.svg)](https://badge.fury.io/nu/DbEx) | [Link](./src/DbEx)\n`DbEx.MySql` | [![NuGet version](https://badge.fury.io/nu/DbEx.MySql.svg)](https://badge.fury.io/nu/DbEx.MySql) | [Link](./src/DbEx.MySql)\n`DbEx.Postgres` | [![NuGet version](https://badge.fury.io/nu/DbEx.Postgres.svg)](https://badge.fury.io/nu/DbEx.Postgres) | [Link](./src/DbEx.Postgres)\n`DbEx.SqlServer` | [![NuGet version](https://badge.fury.io/nu/DbEx.SqlServer.svg)](https://badge.fury.io/nu/DbEx.SqlServer) | [Link](./src/DbEx.SqlServer)\n\n\nThe included [change log](CHANGELOG.md) details all key changes per published version.\n\n\u003cbr/\u003e\n\n## DbUp-inspired\n\n[DbUp](https://dbup.readthedocs.io/en/latest/philosophy-behind-dbup/) is a .NET library that is used to deploy changes to relational databases (supports multiple database technologies). It tracks which SQL scripts have been run already, and runs the change scripts in the order specified that are needed to get a database up to date. \n\nTraditionally, a [Data-tier Application (DAC)](https://docs.microsoft.com/en-us/sql/relational-databases/data-tier-applications/data-tier-applications) is used to provide a logical means to define all of the SQL Server objects - like tables, views, and instance objects, including logins - associated with a database. A DAC is a self-contained unit of SQL Server database deployment that enables data-tier developers and database administrators to package SQL Server objects into a portable artifact called a DAC package, also known as a DACPAC. This is largely specific to Microsoft SQL Server. Alternatively, there are other tools such as [redgate](https://www.red-gate.com/products/sql-development/sql-toolbelt-essentials/) that may be used. DbUp provides a more explicit approach, one that Microsoft similarily adopts with the likes of [EF Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/).\n\n_DbEx_ provides additional functionality to improve the end-to-end experience of managing database migrations/updates leveraging the concepts of DbUp. _DbEx_ prior to version `1.0.14` exclusively leveraged DbUb; however, due to the slow uptake of some key pull requests by the maintainers of _DbUp_ which was starting to impose limitations on _DbEx_. The decision was made to emulate some functionality internally to achieve the functionality goals of _DbEx_. The changes are compatible with the underlying [journaling](./src/DbEx/Migration/IDatabaseJournal.cs) that DbUp leverages (i.e. simulates the same).\n\n\u003cbr/\u003e\n\n## Getting started\n\nThe easiest way to get started is to clone the repository and execute `DbEx.Test.Console` project, this will create a database with data.\n\n``` bash\nDbEx.Test.Console git:(main)\u003e export cs=\"Data Source=localhost, 1433;Initial Catalog=DbEx.Console;User id=sa;Password=Xxxxxx@123;TrustServerCertificate=true\"\nDbEx.Test.Console git:(main)\u003e dotnet run -- -cv cs all\n```\n\nNext, create your own console app, follow the structure of `DbEx.Test.Console` project, add reference to https://www.nuget.org/packages/DbEx, then add in your SQL scripts.\n\nCurrently, the easiest way of generating scripts from an existing database, is to use the `Generate Scripts` feature of _SQL Server Management Studio_ and copy its output.\n\n\u003cbr/\u003e\n\n### Commands (functions)\n\nThe _DbEx_ [`DatabaseMigrationBase`](./src/DbEx/Migration/DatabaseMigrationBase.cs) provides the base database provider agnostic capability, with the likes of the [`SqlServerMigrator`](./src/DbEx.SqlServer/Migration/SqlServerMigration.cs) providing the specific Microsoft SQL Server implementation. This automates the functionality as specified by the [`MigrationCommand`](./src/DbEx/MigrationCommand.cs). One or more commands can be specified, and they will be executed in the order listed.\n\nCommand | Description\n-|-\n`Drop` | Drop the existing database (where it already exists).\n`Create` | Create the database (where it does not already exist).\n[`Migrate`](#Migrate) | Being the upgrading of a database overtime using order-based migration scripts; the tool is consistent with the philosophy of [DbUp](https://dbup.readthedocs.io/en/latest/philosophy-behind-dbup/) to enable.\n`CodeGen` | Provides opportunity to integrate a code-generation step where applicable (none by default).\n[`Schema`](#Schema) | There are a number of database schema objects that can be managed outside of the above migrations, that are dropped and (re-)applied to the database using their native `Create` statement.\n`Reset` | Resets the database by deleting all existing data (exclusions can be configured).\n[`Data`](#Data) | There is data, for example *Reference Data* that needs to be applied to a database. This provides a simpler configuration than specifying the required SQL statements directly (which is also supported). This is _also_ useful for setting up Master and Transaction data for the likes of testing scenarios.\n\nAdditional commands available are:\n\nCommand | Description\n-|-\n`All` | Performs _all_ the primary commands as follows; `Create`, `Migrate`, `CodeGen`, `Schema` and `Data`.\n`Database` | Performs `Create`, `Migrate`, `CodeGen` and `Data`.\n`Deploy` | Performs `Migrate` and `Schema`.\n`DeployWithData` | Performs `Deploy` and `Data`.\n`DropAndAll` | Performs `Drop` and `All`.\n`DropAndDatabase` | Performs `Drop` and `Database`.\n`ResetAndAll` | Performs `Reset` and `All` (designed primarily for testing).\n`ResetAndData` | Performs `Reset` and `Data` (designed primarily for testing).\n`ResetAndDatabase` | Performs `Reset` and `Database` (designed primarily for testing).\n`Execute` | Executes the SQL statement(s) passed as additional arguments.\n`Script` | Creates a new [`migration`](#Migrate) script file using the defined naming convention.\n\n\u003cbr/\u003e\n\n### Migrate\n\nAs stated, the [DbUp](https://dbup.readthedocs.io/en/latest/) approach is used enabling a database to be dropped, created and migrated. The migration is managed by tracking order-based migration scripts. It tracks which SQL scripts have been run already, and runs the change scripts that are needed to get the database up to date. \n\nOver time there will be more than one script updating a single object, for example a `Table`. In this case the first script operation will be a `Create`, followed by subsequent `Alter` operations. The scripts should be considered immutable, in that they cannot be changed once they have been applied; ongoing changes will need additional scripts.\n\nThe migration scripts must be marked as embedded resources, and reside under the `Migrations` folder within the c# project. A naming convention should be used to ensure they are to be executed in the correct order; it is recommended that the name be prefixed by the date and time, followed by a brief description of the purpose. For example: `20181218-081540-create-demo-person-table.sql`\n\nA migration script can contain basic moustache value replacement syntax such as `{{Company}}`, this will then be replaced at runtime by the corresponding `Company` parameter value; see [`MigrationArgs.Parameters`](./src/DbEx/Migration/MigrationArgsBase.cs). These parameters (`Name=Value` pairs) can also be command-line specified.\n\nIt is recommended that each script be enclosed by a transaction that can be rolled back in the case of error; otherwise, a script could be partially applied and will then need manual intervention to resolve.\n\n_Note_: There are _special case_ scripts that will be executed pre- and post- migration deployments. In that any scripts ending with `.pre.deploy.sql` will always be executed before the migrations are attempted, and any scripts ending with `.post.deploy.sql` will always be executed after all the migrations have successfully executed. Finally, any scripts ending with `.post.database.create.sql` will only be executed when (after) the database is created.\n\n\u003cbr/\u003e\n\n### Schema\n\nThere are some key schema objects that can be dropped and created overtime without causing side-effects. Equally, these objects can be code-generated reducing the effort to create and maintain over time. As such, these objects fall outside of the *Migrations* above.\n\nThe currently supported objects are (order specified implies order in which they are applied, and reverse when dropped to allow for dependencies):\n1. [Type](https://docs.microsoft.com/en-us/sql/t-sql/statements/create-type-transact-sql)\n2. [Function](https://docs.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)\n3. [View](https://docs.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql)\n4. [Procedure](https://docs.microsoft.com/en-us/sql/t-sql/statements/create-procedure-transact-sql)\n\nThe schema scripts must be marked as embedded resources, and reside under the `Schema` folder within the c# project. Each script should only contain a single `Create` statement. Each script will be parsed to determine type so that the appropriate order can be applied.\n\nA schema script script can contain basic moustache value replacement syntax such as `{{Company}}`, this will then be replaced at runtime by the corresponding `Company` parameter value; see [`MigrationArgs.Parameters`](./src/DbEx/Migration/MigrationArgsBase.cs). These parameters (`Name=Value` pairs) can also be command-line specified.\n\nThe `Schema` folder is used to encourage the usage of database schemas. Therefore, directly under should be the schema name, for example `dbo` or `Ref`. Then sub-folders for the object types as per [Azure Data Studio](https://docs.microsoft.com/en-au/sql/azure-data-studio/what-is), for example `Functions`, `Stored Procedures` or `Types\\User-Defined Table Types`. \n\n\u003cbr/\u003e\n\n### Data\n\nData can be defined using [YAML](https://en.wikipedia.org/wiki/YAML) or JSON to enable simplified configuration that will be used to generate the required SQL statements to apply to the database.\n\nThe data specified follows a basic indenting/levelling rule to enable:\n1. **Schema** - specifies Schema name.\n2. **Table** - specifies the Table name within the Schema; this will be validated to ensure it exists within the database as the underlying table schema (columns) will be inferred. The underyling rows will be [inserted](https://docs.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql) by default; or alternatively by prefixing with a `$` character a [merge](https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql) operation will be performed instead.\n3. **Rows** - each row specifies the column name and the corresponding values (except for reference data described below). The tooling will parse each column value according to the underying SQL type.\n\nAdditionally, SQL script files can also be provided in addition to YAML and JSON where explicit SQL is to be executed.\n\n\u003cbr/\u003e\n\n#### Reference data\n\n*Reference Data* is treated as a special case. The first column name and value pair are treated as the `Code` and `Text` columns; as defined via the [`DataParserArgs`](./src/DbEx/Migration/Data/DataParserArgs.cs) (see `RefDataCodeColumnName` and `RefDataTextColumnName` properties). \n\nWhere a column is a *Reference Data* reference the reference data code can be specified, with the identifier being determined at runtime (using a sub-query) as it is unlikely to be known at configuration time. The tooling determines this by the column name being suffixed by `Id` and a foreign-key constraint being defined.\n\nAlternatively, a *Reference Data* reference could be the code itself, typically named XxxCode (e.g. `GenderCode`). This has the advantage of decoupling the reference data references from the underlying identifier. Where data is persisted as JSON then the **code** is used; this would ensure consistency. The primary disadvantage is that the **code** absolutely becomes _immutable_ and therefore not easily changed; for the most part this typically is not an issue.\n\n\u003cbr/\u003e\n\n#### YAML/JSON configuration\n\nExample YAML configuration for *merging* reference data is as follows.\n\n``` YAML\nRef:\n  - $Gender:\n    - M: Male\n    - F: Female\n```\n\nExample YAML configuration for *inserting* data (also inferring the `GenderId` from the specified reference data code) is as follows.\n\n``` YAML\nDemo:\n  - Person:\n    - { FirstName: Wendy, LastName: Jones, Gender: F, Birthday: 1985-03-18 }\n    - { FirstName: Brian, LastName: Smith, Gender: M, Birthday: 1994-11-07 }\n    - { FirstName: Rachael, LastName: Browne, Gender: F, Birthday: 1972-06-28, Street: 25 Upoko Road, City: Wellington }\n    - { FirstName: Waylon, LastName: Smithers, Gender: M, Birthday: 1952-02-21 }\n  - WorkHistory:\n    - { PersonId: 2, Name: Telstra, StartDate: 2015-05-23, EndDate: 2016-04-06 }\n    - { PersonId: 2, Name: Optus, StartDate: 2016-04-16 }\n```\n\nAdditionally, to use an [`IIdentifierGenerator`](./src/DbEx/Migration/Data/IIdentifierGenerator.cs) to generate the identifiers the [`DataParserArgs`](./src/DbEx/Migration/Data/DataParserArgs.cs) `IdentifierGenerator` property must be specified (this defaults to  [`GuidIdentifierGenerator`](./src/DbEx/Migration/Data/GuidIdentifierGenerator.cs)). For this to be used the `^` prefix must be specified for each corresponding table (must opt-in); must occur after `$` merge character where specified. Example as follows.\n\n``` yaml\nRef:\n  - $^Gender:\n    - { Code: M, Text: Male, TripCode: Male }\nDemo:\n  - ^Person:\n    - { FirstName: Wendy, LastName: Jones, Gender: F, Birthday: 1985-03-18 }\n```\n\nRuntime values can be used within the YAML using the value lookup notation; this notation is `^(Key)`. This will either reference the [`DataParserArgs`](./src/DbEx/Migration/Data/DataParserArgs.cs) `Parameters` property using the specified key. There are two special parameters, being `UserName` and `DateTimeNow`, that reference the same named `DataParserArgs` properties. An additional special parameter being `GuidNew`, that results in a `Guid.NewGuid`. Where not found the extended notation `^(Namespace.Type.Property.Method().etc, AssemblyName)` is used. Where the `AssemblyName` is not specified then the default `mscorlib` is assumed. The `System` root namespace is optional, i.e. it will be attempted by default. The initial property or method for a `Type` must be `static`, in that the `Type` will not be instantiated. These parameters (`Name=Value` pairs) can also be command-line specified.\n\nAdditionally, a column can be set with a guid representation of an integer where specified using shorthand notation; i.e. replace `^n` values where `n` is an integer with a guid equivalent; e.g. `^1` will be converted to `00000001-0000-0000-0000-000000000000`. The `DataParserArgs.ReplaceShorthandGuids` had been added to control this behavior (defaults to `true`).\n\nExample as follows. \n\n``` yaml\nDemo:\n  - Person:\n    - { PersonId: ^1, FirstName: Wendy, Username: ^(System.Security.Principal.WindowsIdentity.GetCurrent().Name,System.Security.Principal.Windows), Birthday: ^(DateTimeNow) }\n    - { PersonId: ^2, FirstName: Wendy, Username: ^(Beef.ExecutionContext.EnvironmentUsername,Beef.Core), Birthday: ^(DateTime.UtcNow) }\n```\n\nAdvanced capabilities, such as nested YAML/JSON can be specified to represent hierarchical relationships (see `contact-\u003eaddresses` within test [`data.yaml`](./tests/DbEx.Test.Console/Data/Data.yaml) and related [`TableNameMappings`](./tests/DbEx.Test.Console/Program.cs) to map to the correct underlying database table). [`DataConfig`](./src/Dbex/Migration/Data/DataConfig.cs) can also be specified using the `*` schema to control the behaviour within the context of a YAML/JSON file as demonstrated by the test [`ContactType.json`](./tests/DbEx.Test.Console/Data/ContactType.json).\n\n\n\u003cbr/\u003e\n\n### Console application\n\n[`DbEx`](./src/DbEx/Console/MigrationConsoleBase.cs) has been optimized so that a new console application can reference and inherit the underlying capabilities.\n\nWhere executing directly the default command-line options are as follows.\n\n```\nXxx Database Tool.\n\nUsage: Xxx [options] \u003ccommand\u003e \u003cargs\u003e\n\nArguments:\n  command                    Database migration command (see https://github.com/Avanade/dbex#commands-functions).\n                             Allowed values are: None, Drop, Create, Migrate, CodeGen, Schema, Deploy, Reset, Data, DeployWithData, Database, DropAndDatabase, All, DropAndAll,\n                             ResetAndData, ResetAndDatabase, ResetAndAll, Execute, Script.\n  args                       Additional arguments; 'Script' arguments (first being the script name) -or- 'Execute' (each a SQL statement to invoke).\n\nOptions:\n  -?|-h|--help               Show help information.\n  -cs|--connection-string    Database connection string.\n  -cv|--connection-varname   Database connection string environment variable name.\n  -so|--schema-order         Database schema name (multiple can be specified in priority order).\n  -o|--output                Output directory path.\n  -a|--assembly              Assembly containing embedded resources (multiple can be specified in probing order).\n  -p|--param                 Parameter expressed as a 'Name=Value' pair (multiple can be specified).\n  -eo|--entry-assembly-only  Use the entry assembly only (ignore all other assemblies).\n  --accept-prompts           Accept prompts; command should _not_ stop and wait for user confirmation (DROP or RESET commands).\n```\n\nThe [`DbEx.Test.Console`](./tests/DbEx.Test.Console) demonstrates how this can be leveraged. The command-line arguments need to be passed through to support the standard options. Additional methods exist to specify defaults or change behaviour as required. An example [`Program.cs`](./tests/DbEx.Test.Console/Program.cs) is as follows.\n\n```\nusing DbEx.Console;\nusing System.Threading.Tasks;\n\nnamespace DbEx.Test.Console\n{\n    public class Program \n    {\n        internal static Task\u003cint\u003e Main(string[] args) =\u003e SqlServerMigratorConsole\n            .Create\u003cProgram\u003e(\"Data Source=.;Initial Catalog=DbEx.Console;Integrated Security=True\")\n            .RunAsync(args);\n    }\n}\n```\n\n_Tip:_ To ensure all files are included as embedded resources add the following to the .NET project:\n\n``` xml\n\u003cItemGroup\u003e\n  \u003cEmbeddedResource Include=\"Schema\\**\\*\" /\u003e\n  \u003cEmbeddedResource Include=\"Migrations\\**\\*\" /\u003e\n  \u003cEmbeddedResource Include=\"Data\\**\\*\" /\u003e\n\u003c/ItemGroup\u003e\n```\n\n\u003cbr/\u003e\n\n#### Script command\n\nTo simplify the process for the developer _DbEx_ enables the creation of new migration script files into the `Migrations` folder. This will name the script file correctly and output the basic SQL statements to perform the selected function. The date and time stamp will use [DateTime.UtcNow](https://docs.microsoft.com/en-us/dotnet/api/system.datetime.utcnow) as this should avoid conflicts where being co-developed across time zones. \n\nThis requires the usage of the `Script` command, plus zero or more optional arguments where the first is the sub-command (these are will depend on the script being created). The optional arguments must appear in the order listed; where not specified it will default within the script file. Depending on the database provider not all of the following will be supported.\n\nThe following shows the `Script` sub-commands for SQL Server. Use `--help` to see the commands available at rubntime.\n\nSub-command | Argument(s) | Description\n-|-|-\n[N/A](./src/DbEx.SqlServer/Resources/ScriptDefault_sql.hbs) | N/A | Creates a new empty skeleton script file.\n[`Schema`](./src/DbEx.SqlServer/Resources/ScriptSchema_sql.hbs) | `Schema` and `Table` | Creates a new table create script file for the named schema and table.\n[`Create`](./src/DbEx.SqlServer/Resources/ScriptCreate_sql.hbs) | `Schema` and `Table` | Creates a new table create script file for the named schema and table.\n[`RefData`](./src/DbEx.SqlServer/Resources/ScriptRefData_sql.hbs) | `Schema` and `Table` | Creates a new reference data table create script file for the named schema and table.\n[`Alter`](./src/DbEx.SqlServer/Resources/ScriptAlter_sql.hbs) | `Schema` and `Table` | Creates a new table alter script file for the named schema and table.\n[`CdcDb`](./src/DbEx.SqlServer/Resources/ScriptCdcDb_sql.hbs) | N/A | Creates a new `sys.sp_cdc_enable_db` script file for the database.\n[`Cdc`](./src/DbEx.SqlServer/Resources/ScriptCdc_sql.hbs) | `Schema` and `Table` | Creates a new `sys.sp_cdc_enable_table` script file for the named schema and table.\n\nExamples as follows.\n\n```\ndotnet run script\ndotent run script schema Foo\ndotnet run script create Foo Bar\ndotnet run script refdata Foo Gender\ndotnet run script alter Foo Bar\ndotnet run script cdcdb\ndotnet run script cdc Foo Bar\n```\n\n#### Execute command\n\nThe execute command allows one or more SQL Statements, and/or Script files, to be executed directly against the database. This is intended for enabling commands to be executed only. No response other than success or failure will be acknowledged; as such this is not intended for performing queries.\n\nExamples as follows.\n\n```\ndotnet run execute \"create schema [Xyz] authorization [dbo]\"\ndotnet run execute ./schema/createscehma.sql\n```\n\n\u003cbr/\u003e\n\n## Infer database schema\n\nWithin a code-generation, or other context, the database schema may need to be inferred to understand the basic schema for all tables and their corresponding columns.\n\nThe [`Database`](./src/DbEx/DatabaseExtensions.cs) class provides a `SelectSchemaAsync` method to return a [`DbTableSchema`](./src/DbEx/DbSchema/DbTableSchema.cs) list, including the respective columns for each table (see [`DbColumnSchema`](./src/DbEx/DbSchema/DbColumnSchema.cs)).\n\n\u003cbr/\u003e\n\n## Other considerations\n\nTo simplify the database management here are some further considerations that may make life easier over time; especially where you adopt the philosophy that the underlying busines logic (within the application APIs) is primarily responsible for the consistency of the data; and the data source (the database) is being largely used for storage and advanced query:\n\n- **Minimise constraints** - do not use database constraints unless absolutely necessary; only leverage where the database is the best and/or most efficient means to perform; i.e. uniqueness. The business logic should validate the request to ensure that any related data is provided, is valid and consistent. \n- **No cross-schema referencing** - avoid referencing across `Schemas` where possible as this may impact the Migrations as part of this tooling; and we should not be using constraints as per prior point. Each schema is considered independent of others (where using a schema per domain) except in special cases, such as `dbo` or `sec` (security where used) for example.\n- **JSON for schema-less** - where there is data that needs to be persisted, but rarely searched on, a schema-less approach should be considered such that a JSON object is persisted into a single column versus having to define additional tables and/or columns. This can further simplify the database requirements where the data is hierarchical in nature. To enable the [`ObjectToJsonConverter`](https://github.com/Avanade/CoreEx/blob/main/src/CoreEx/Mapping/Converters/ObjectToJsonConverter.cs) and [`AutoMapperObjectToJsonConverter`](https://github.com/Avanade/CoreEx/blob/main/src/CoreEx.AutoMapper/Converters/AutoMapperObjectToJsonConverter.cs) can be used within the corresponding mapper to enable.\n- **Nullable everything** - all columns (except) the primary key should be defined as nullable. The business logic should validate the request to ensure data is provided where mandatory. Makes changes to the database schema easier over time without this constraint.\n\n\u003cbr/\u003e\n\n\n## Other repos\n\nThese other _Avanade_ repositories leverage _DbEx_:\n- [*NTangle*](https://github.com/Avanade/NTangle) - Change Data Capture (CDC) code generation tool and runtime.\n- [*Beef*](https://github.com/Avanade/Beef) - Business Entity Execution Framework to enable industralisation of API development.\n\n\u003cbr/\u003e\n\n## License\n\n_DbEx_ is open source under the [MIT license](./LICENSE) and is free for commercial use.\n\n\u003cbr/\u003e\n\n## Contributing\n\nOne of the easiest ways to contribute is to participate in discussions on GitHub issues. You can also contribute by submitting pull requests (PR) with code changes. Contributions are welcome. See information on [contributing](./CONTRIBUTING.md), as well as our [code of conduct](https://avanade.github.io/code-of-conduct/).\n\n\u003cbr/\u003e\n\n## Security\n\nSee our [security disclosure](./SECURITY.md) policy.\n\n\u003cbr/\u003e\n\n## Who is Avanade?\n\n[Avanade](https://www.avanade.com) is the leading provider of innovative digital and cloud services, business solutions and design-led experiences on the Microsoft ecosystem, and the power behind the Accenture Microsoft Business Group.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favanade%2Fdbex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favanade%2Fdbex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favanade%2Fdbex/lists"}