From a7c01c7472cabfe227c9edda195a2c7cc31780de Mon Sep 17 00:00:00 2001 From: AJ Matthews Date: Mon, 9 Jun 2025 17:45:41 +0100 Subject: [PATCH 1/5] Initial corrections. --- docs/database/seed-database-data.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/database/seed-database-data.md b/docs/database/seed-database-data.md index 493a49b443..44f02410bb 100644 --- a/docs/database/seed-database-data.md +++ b/docs/database/seed-database-data.md @@ -36,11 +36,11 @@ By default, .NET Aspire database integrations rely on containerized databases, w ## Seed data using SQL scripts -In .NET Aspire 9.2, the recommended method for executing database seeding scripts depends on the database server you use: +In .NET Aspire 9.3, the recommended method for executing database seeding scripts depends on the database server you use: ### [SQL Server](#tab/sql-server) -In .NET Aspire 9.2 and later versions, you can use the method to ensure a T-SQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. +In .NET Aspire 9.3 and later versions, you can use the method to ensure a T-SQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. The following code is an example T-SQL script that creates and populates an address book database: From f88b741a5ec1c8b46a7a0d6843ad8e33fb890561 Mon Sep 17 00:00:00 2001 From: AJ Matthews Date: Tue, 10 Jun 2025 15:25:43 +0100 Subject: [PATCH 2/5] Updated MySQL and PostgreSQL data seeding sections for Apsire 9.3 --- docs/database/seed-database-data.md | 18 ++++++--- .../mysql-seed-data/.aspire/settings.json | 3 ++ .../snippets/mysql-seed-data/AppHost.cs | 37 +++++++++++++++++++ .../mysql-seed-data/MySQLSeedData.csproj | 18 +++++++++ .../Properties/launchSettings.json | 29 +++++++++++++++ .../appsettings.Development.json | 8 ++++ .../snippets/mysql-seed-data/appsettings.json | 9 +++++ .../mysql-seed-data/mysql-seed-data.sln | 24 ++++++++++++ 8 files changed, 140 insertions(+), 6 deletions(-) create mode 100644 docs/database/snippets/mysql-seed-data/.aspire/settings.json create mode 100644 docs/database/snippets/mysql-seed-data/AppHost.cs create mode 100644 docs/database/snippets/mysql-seed-data/MySQLSeedData.csproj create mode 100644 docs/database/snippets/mysql-seed-data/Properties/launchSettings.json create mode 100644 docs/database/snippets/mysql-seed-data/appsettings.Development.json create mode 100644 docs/database/snippets/mysql-seed-data/appsettings.json create mode 100644 docs/database/snippets/mysql-seed-data/mysql-seed-data.sln diff --git a/docs/database/seed-database-data.md b/docs/database/seed-database-data.md index 44f02410bb..d885b91106 100644 --- a/docs/database/seed-database-data.md +++ b/docs/database/seed-database-data.md @@ -65,7 +65,7 @@ This code: ### [PostgreSQL](#tab/postgresql) -In .NET Aspire 9.2, the `WithCreationScript()` method isn't supported for the PostgreSQL integration. Instead, you must use a bind mount and deploy the setup SQL script to it, so that the data is seeded when the container initializes the database. +In .NET Aspire 9.3, the `WithCreationScript()` method is supported for the PostgreSQL integration but, because there is no `USE DATABASE` in PostgreSQL, it only supports operations against the default database. For example, you can issue `CREATE DATABASE` statements to create other databases, but you can't populate them with tables and data. Instead, you must use a bind mount and deploy the setup SQL script to it, so that the data is seeded when the container initializes the database. The following code is an example PostgreSQL script that creates and populates a to do list database: @@ -77,15 +77,21 @@ In the app host's *AppHost.cs* (or *Program.cs*) file, create the database and m ### [MySQL](#tab/mysql) -In .NET Aspire 9.2, the `WithCreationScript()` method isn't supported for the MySQL integration. Instead, you must use a bind mount and deploy the setup SQL script to it, so that the data is seeded when the container initializes the database. +In .NET Aspire 9.3 and later versions, you can use the method to ensure a MySQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. -The following code is an example MySQL script that creates and populates a product catalog database: +In the following App Host code, the script is created as a string and passed to the `WithCreationScript` method: -:::code source="~/aspire-samples/samples/DatabaseContainers/DatabaseContainers.ApiService/data/mysql/init.sql" ::: +:::code source="../snippets/mysql-seed-data/AppHost.cs" ::: -In the app host's *AppHost.cs* (or *Program.cs*) file, create the database and mount the folder that contains the SQL script as a bind mount: +This code: + +- Create a MySQL container by calling `builder.AddMySql()`. +- Uses the `MYSQL_DATABASE` environment variable to name the database `catalog`. +- Ensures that data is persisted across debugging sessions by calling `WithDataVolume()` and `WithLifetime(ContainerLifetime.Persistent)`. +- Create a second container that runs the PHP My Admin user interface for MySQL. +- Calls `WithCreationScript()` to create and seed the database. -:::code source="~/aspire-samples/samples/DatabaseContainers/DatabaseContainers.AppHost/AppHost.cs" range="21-36" ::: +If you run this code, you can use the PHP My Admin resource to check that a table called **catalog** has been created and populated with products. --- diff --git a/docs/database/snippets/mysql-seed-data/.aspire/settings.json b/docs/database/snippets/mysql-seed-data/.aspire/settings.json new file mode 100644 index 0000000000..17c5d25ab1 --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/.aspire/settings.json @@ -0,0 +1,3 @@ +{ + "appHostPath": "../MySQLSeedData.csproj" +} \ No newline at end of file diff --git a/docs/database/snippets/mysql-seed-data/AppHost.cs b/docs/database/snippets/mysql-seed-data/AppHost.cs new file mode 100644 index 0000000000..b7d2ef03ec --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/AppHost.cs @@ -0,0 +1,37 @@ +var builder = DistributedApplication.CreateBuilder(args); + +var catalogDbName = "catalog"; + +var mysql = builder.AddMySql("mysql") + .WithEnvironment("MYSQL_DATABASE", catalogDbName) + .WithDataVolume() + .WithLifetime(ContainerLifetime.Persistent) + .WithPhpMyAdmin(); + +var creationScript = $$""" +USE catalog; +CREATE TABLE IF NOT EXISTS `catalog` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `description` varchar(255) NOT NULL, + `price` DECIMAL(18,2) NOT NULL, + PRIMARY KEY (`id`) +); + +-- Insert some sample data into the Catalog table only if the table is empty +INSERT INTO catalog (name, description, price) +SELECT * +FROM ( + SELECT '.NET Bot Black Hoodie', 'This hoodie will keep you warm while looking cool and representing .NET!', 19.5 UNION ALL + SELECT '.NET Black & White Mug', 'The perfect place to keep your favorite beverage while you code.', 8.5 UNION ALL + SELECT 'Prism White T-Shirt', "It's a t-shirt, it's white, and it can be yours.", 12 + ) data +-- This clause ensures the rows are only inserted if the table is empty +WHERE NOT EXISTS (SELECT NULL FROM catalog) +"""; + +var mysqldb = mysql.AddDatabase(catalogDbName) + .WithCreationScript(creationScript); + +builder.Build().Run(); diff --git a/docs/database/snippets/mysql-seed-data/MySQLSeedData.csproj b/docs/database/snippets/mysql-seed-data/MySQLSeedData.csproj new file mode 100644 index 0000000000..5709a9f183 --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/MySQLSeedData.csproj @@ -0,0 +1,18 @@ + + + + + + Exe + net9.0 + enable + enable + 2f0f3679-5f3c-4fe7-957d-ec0d9fabfda4 + + + + + + + + diff --git a/docs/database/snippets/mysql-seed-data/Properties/launchSettings.json b/docs/database/snippets/mysql-seed-data/Properties/launchSettings.json new file mode 100644 index 0000000000..f8f95f112b --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:17022;http://localhost:15236", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21048", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22281" + } + }, + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15236", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19255", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20128" + } + } + } +} diff --git a/docs/database/snippets/mysql-seed-data/appsettings.Development.json b/docs/database/snippets/mysql-seed-data/appsettings.Development.json new file mode 100644 index 0000000000..0c208ae918 --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/docs/database/snippets/mysql-seed-data/appsettings.json b/docs/database/snippets/mysql-seed-data/appsettings.json new file mode 100644 index 0000000000..31c092aa45 --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/docs/database/snippets/mysql-seed-data/mysql-seed-data.sln b/docs/database/snippets/mysql-seed-data/mysql-seed-data.sln new file mode 100644 index 0000000000..1eb903c01c --- /dev/null +++ b/docs/database/snippets/mysql-seed-data/mysql-seed-data.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySQLSeedData", "MySQLSeedData.csproj", "{62FFBCD3-B001-5E15-DD62-F84BFCFEA366}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {62FFBCD3-B001-5E15-DD62-F84BFCFEA366}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62FFBCD3-B001-5E15-DD62-F84BFCFEA366}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62FFBCD3-B001-5E15-DD62-F84BFCFEA366}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62FFBCD3-B001-5E15-DD62-F84BFCFEA366}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {349C2004-BE30-4CFC-93D4-5995A9408BF3} + EndGlobalSection +EndGlobal From 3e4e58400159faf5d4752b02d4f0c7ac708854a4 Mon Sep 17 00:00:00 2001 From: AJ Matthews Date: Tue, 10 Jun 2025 15:33:31 +0100 Subject: [PATCH 3/5] One small correction. --- docs/database/seed-database-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/seed-database-data.md b/docs/database/seed-database-data.md index d885b91106..bd77b9b196 100644 --- a/docs/database/seed-database-data.md +++ b/docs/database/seed-database-data.md @@ -102,7 +102,7 @@ You can also seed data in .NET Aspire projects using EF Core by explicitly runni > [!IMPORTANT] > These types of configurations should only be done during development, so make sure to add a conditional that checks your current environment context. -Add the following code to the _:::no-loc text="Program.cs"::: file of your **API Service** project. +Add the following code to the _:::no-loc text="Program.cs":::_ file of your **API Service** project. ### [SQL Server](#tab/sql-server) From d0f8ee171600c86a92ad4715716926587b728b98 Mon Sep 17 00:00:00 2001 From: AJ Matthews Date: Tue, 10 Jun 2025 15:47:15 +0100 Subject: [PATCH 4/5] Corrected one code link. --- docs/database/seed-database-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/database/seed-database-data.md b/docs/database/seed-database-data.md index bd77b9b196..27eafaacb8 100644 --- a/docs/database/seed-database-data.md +++ b/docs/database/seed-database-data.md @@ -81,7 +81,7 @@ In .NET Aspire 9.3 and later versions, you can use the Date: Wed, 11 Jun 2025 10:49:57 +0100 Subject: [PATCH 5/5] Incorporated feedback from @adegeo. --- docs/database/seed-database-data.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/database/seed-database-data.md b/docs/database/seed-database-data.md index 27eafaacb8..ad5a59622b 100644 --- a/docs/database/seed-database-data.md +++ b/docs/database/seed-database-data.md @@ -36,11 +36,11 @@ By default, .NET Aspire database integrations rely on containerized databases, w ## Seed data using SQL scripts -In .NET Aspire 9.3, the recommended method for executing database seeding scripts depends on the database server you use: +The recommended method for executing database seeding scripts depends on the database server you use: ### [SQL Server](#tab/sql-server) -In .NET Aspire 9.3 and later versions, you can use the method to ensure a T-SQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. +Starting with .NET Aspire 9.2, you can use the method to ensure a T-SQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. The following code is an example T-SQL script that creates and populates an address book database: @@ -56,7 +56,7 @@ Next, in the app host's *AppHost.cs* (or *Program.cs*) file, create the database :::code source="~/aspire-samples/samples/DatabaseContainers/DatabaseContainers.AppHost/AppHost.cs" range="40-49" ::: -This code: +The preceding code: - Create a SQL Server container by calling `builder.AddSqlServer()`. - Ensures that data is persisted across debugging sessions by calling `WithDataVolume()` and `WithLifetime(ContainerLifetime.Persistent)`. @@ -65,7 +65,7 @@ This code: ### [PostgreSQL](#tab/postgresql) -In .NET Aspire 9.3, the `WithCreationScript()` method is supported for the PostgreSQL integration but, because there is no `USE DATABASE` in PostgreSQL, it only supports operations against the default database. For example, you can issue `CREATE DATABASE` statements to create other databases, but you can't populate them with tables and data. Instead, you must use a bind mount and deploy the setup SQL script to it, so that the data is seeded when the container initializes the database. +Starting with .NET Aspire 9.3, the `WithCreationScript()` method is supported for the PostgreSQL integration but, because there is no `USE DATABASE` in PostgreSQL, it only supports operations against the default database. For example, you can issue `CREATE DATABASE` statements to create other databases, but you can't populate them with tables and data. Instead, you must use a bind mount and deploy the setup SQL script to it, so that the data is seeded when the container initializes the database. The following code is an example PostgreSQL script that creates and populates a to do list database: @@ -77,13 +77,13 @@ In the app host's *AppHost.cs* (or *Program.cs*) file, create the database and m ### [MySQL](#tab/mysql) -In .NET Aspire 9.3 and later versions, you can use the method to ensure a MySQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. +Starting with .NET Aspire 9.3, you can use the method to ensure a MySQL script is run when the database is created. Add SQL code to this script that creates and populates the database, the necessary tables, and other database objects. In the following App Host code, the script is created as a string and passed to the `WithCreationScript` method: :::code source="snippets/mysql-seed-data/AppHost.cs" ::: -This code: +The preceding code: - Create a MySQL container by calling `builder.AddMySql()`. - Uses the `MYSQL_DATABASE` environment variable to name the database `catalog`.