diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index c95da48..a38a9fa 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -294,11 +294,26 @@ dotnet ef database update --project src/Dotnet.Samples.AspNetCore.WebApi ./scripts/run-migrations-and-copy-database.sh ``` -**Important**: The `run-migrations-and-copy-database.sh` script: -- Resets the placeholder database file -- Runs all migrations -- Copies the generated database from `bin/Debug/net8.0/Data/` to `Data/` -- Requires `dotnet ef` CLI tool installed globally +**Database Workflow Explained:** + +The project maintains a **pre-seeded database** at `storage/players-sqlite3.db` to support three use cases: +1. **Clone & Run** - Developers can clone the repo and run immediately without manual DB setup +2. **Recreate from Scratch** - Use the script to rebuild the database with all migrations +3. **Docker** - Container gets a copy of the pre-seeded database on first startup + +**How `run-migrations-and-copy-database.sh` works:** +1. **Creates empty file** at `storage/players-sqlite3.db` (version-controlled source location) +2. **Runs migrations** via `dotnet ef database update` + - EF Core uses `AppContext.BaseDirectory/storage/players-sqlite3.db` + - During migration, `AppContext.BaseDirectory` = `bin/Debug/net8.0/` + - EF Core creates/updates database at `bin/Debug/net8.0/storage/players-sqlite3.db` + - Applies all migrations: creates schema, seeds 26 players (11 starting + 15 substitutes) +3. **Copies migration-applied database** from `bin/Debug/net8.0/storage/` back to `storage/` + - Updates the version-controlled database with latest schema + seed data + - This file is included in git and copied to build output via `.csproj` configuration + +**Requirements:** +- `dotnet ef` CLI tool installed globally (`dotnet tool install --global dotnet-ef`) ### Docker Operations ```bash @@ -325,9 +340,9 @@ docker compose down -v ## 🚨 Common Issues & Workarounds ### Database Path Issues -- **SQLite database location**: `storage/players-sqlite3.db` relative to binary output -- **Container storage**: `/storage/players-sqlite3.db` (mounted volume) -- **Environment variable**: `STORAGE_PATH` can override the default path in containers +- **Development**: `storage/players-sqlite3.db` (source, copied to `bin/Debug/net8.0/storage/` during build) +- **Container**: Pre-seeded database copied from image `/app/hold/` to volume `/storage/` on first run +- **Runtime**: Application uses `AppContext.BaseDirectory/storage/players-sqlite3.db` ### Validation Patterns - **FluentValidation** runs in the validator class for input format/structure diff --git a/README.md b/README.md index fba09c6..37551d3 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ src/Dotnet.Samples.AspNetCore.WebApi/ │ ├── Player.cs │ ├── PlayerRequestModel.cs │ └── PlayerResponseModel.cs -├── Data/ # EF Core DbContext +├── Data/ # EF Core DbContext and migrations │ └── PlayerDbContext.cs ├── Mappings/ # AutoMapper profiles │ └── PlayerMappingProfile.cs diff --git a/scripts/run-migrations-and-copy-database.sh b/scripts/run-migrations-and-copy-database.sh old mode 100755 new mode 100644 index f86a26d..83631d1 --- a/scripts/run-migrations-and-copy-database.sh +++ b/scripts/run-migrations-and-copy-database.sh @@ -5,9 +5,11 @@ DATA_FILE="players-sqlite3.db" PROJECT_ROOT_PATH="src/Dotnet.Samples.AspNetCore.WebApi" PROJECT_BASE_PATH="$PROJECT_ROOT_PATH/bin/Debug/net8.0" -SOURCE_FILE_PATH="$PROJECT_BASE_PATH/Data/$DATA_FILE" -TARGET_FILE_PATH="$PROJECT_ROOT_PATH/Data/$DATA_FILE" +SOURCE_FILE_PATH="$PROJECT_BASE_PATH/storage/$DATA_FILE" +TARGET_FILE_PATH="$PROJECT_ROOT_PATH/storage/$DATA_FILE" +# log prints a formatted log message prefixed by an emoji and timestamp, followed by the log level and message. +# Parameters: emoji — emoji or symbol to prefix the entry; level — severity or level label; message — the log text. log() { local emoji=$1 local level=$2 @@ -60,4 +62,4 @@ if [ -f "$TARGET_FILE_PATH" ]; then else log "⚠️" "WARNING" "Something went wrong. The destination file was not found." exit 1 -fi +fi \ No newline at end of file diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/20251221220614_SeedSubstitutes.Designer.cs b/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/20251221220614_SeedSubstitutes.Designer.cs new file mode 100644 index 0000000..f7f7b89 --- /dev/null +++ b/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/20251221220614_SeedSubstitutes.Designer.cs @@ -0,0 +1,69 @@ +// +using System; +using Dotnet.Samples.AspNetCore.WebApi.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Dotnet.Samples.AspNetCore.WebApi.Migrations +{ + [DbContext(typeof(PlayerDbContext))] + [Migration("20251221220614_SeedSubstitutes")] + partial class SeedSubstitutes + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "9.0.11"); + + modelBuilder.Entity("Dotnet.Samples.AspNetCore.WebApi.Models.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AbbrPosition") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("League") + .HasColumnType("TEXT"); + + b.Property("MiddleName") + .HasColumnType("TEXT"); + + b.Property("Position") + .HasColumnType("TEXT"); + + b.Property("SquadNumber") + .HasColumnType("INTEGER"); + + b.Property("Starting11") + .HasColumnType("INTEGER"); + + b.Property("Team") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SquadNumber") + .IsUnique(); + + b.ToTable("Players"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/20251221220614_SeedSubstitutes.cs b/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/20251221220614_SeedSubstitutes.cs new file mode 100644 index 0000000..b4e4ffc --- /dev/null +++ b/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/20251221220614_SeedSubstitutes.cs @@ -0,0 +1,62 @@ +using Dotnet.Samples.AspNetCore.WebApi.Utilities; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Dotnet.Samples.AspNetCore.WebApi.Migrations +{ + /// + public partial class SeedSubstitutes : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + var substitutes = PlayerData.GetSubstitutesWithId(); + + foreach (var player in substitutes) + { + migrationBuilder.InsertData( + table: "Players", + columns: + [ + "Id", + "FirstName", + "MiddleName", + "LastName", + "DateOfBirth", + "SquadNumber", + "Position", + "AbbrPosition", + "Team", + "League", + "Starting11" + ], + values: new object[] + { + player.Id, + player.FirstName, + player.MiddleName, + player.LastName, + player.DateOfBirth, + player.SquadNumber, + player.Position, + player.AbbrPosition, + player.Team, + player.League, + player.Starting11 + } + ); + } + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + var substitutes = PlayerData.GetSubstitutesWithId(); + foreach (var player in substitutes) + { + migrationBuilder.DeleteData(table: "Players", keyColumn: "Id", keyValue: player.Id); + } + } + } +} diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/PlayerDbContextModelSnapshot.cs b/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/PlayerDbContextModelSnapshot.cs index 79ae23e..d1c92e8 100644 --- a/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/PlayerDbContextModelSnapshot.cs +++ b/src/Dotnet.Samples.AspNetCore.WebApi/Migrations/PlayerDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ partial class PlayerDbContextModelSnapshot : ModelSnapshot protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "9.0.4"); + modelBuilder.HasAnnotation("ProductVersion", "9.0.11"); modelBuilder.Entity("Dotnet.Samples.AspNetCore.WebApi.Models.Player", b => { diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/Utilities/PlayerData.cs b/src/Dotnet.Samples.AspNetCore.WebApi/Utilities/PlayerData.cs index 968e8f4..1b986e6 100644 --- a/src/Dotnet.Samples.AspNetCore.WebApi/Utilities/PlayerData.cs +++ b/src/Dotnet.Samples.AspNetCore.WebApi/Utilities/PlayerData.cs @@ -1,4 +1,4 @@ -using System.Text.Json; +using System.Text.Json; using Dotnet.Samples.AspNetCore.WebApi.Enums; using Dotnet.Samples.AspNetCore.WebApi.Models; @@ -153,6 +153,10 @@ public static List MakeStarting11() ]; } + /// + /// Create a predefined starting eleven of players where each player has a fixed GUID identifier and full profile data. + /// + /// A list of 11 Player instances representing the starting lineup; each entry includes a predefined Id (Guid) and populated fields such as name, date of birth, squad number, position (and abbreviation), team, league, and Starting11 set to true. public static List MakeStarting11WithId() { return @@ -311,6 +315,427 @@ public static List MakeStarting11WithId() ]; } + /// + /// Create a predefined list of 15 substitute players with full profile data but without Id values. + /// + /// A list of 15 Player instances representing substitute players; each entry includes populated fields such as name, date of birth, squad number, position (and abbreviation), team, league, and Starting11 set to false. Id values are not assigned. + public static List GetSubstitutes() + { + return + [ + new() + { + FirstName = "Franco", + MiddleName = "Daniel", + LastName = "Armani", + DateOfBirth = new DateTime(1986, 10, 16, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 1, + Position = Position.Goalkeeper.Text, + AbbrPosition = Position.Goalkeeper.Abbr, + Team = "River Plate", + League = "Copa de la Liga", + Starting11 = false, + }, + new() + { + FirstName = "Gerónimo", + LastName = "Rulli", + DateOfBirth = new DateTime(1992, 5, 20, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 12, + Position = Position.Goalkeeper.Text, + AbbrPosition = Position.Goalkeeper.Abbr, + Team = "Ajax Amsterdam", + League = "Eredivisie", + Starting11 = false, + }, + new() + { + FirstName = "Juan", + MiddleName = "Marcos", + LastName = "Foyth", + DateOfBirth = new DateTime(1998, 1, 12, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 2, + Position = Position.RightBack.Text, + AbbrPosition = Position.RightBack.Abbr, + Team = "Villarreal", + League = "La Liga", + Starting11 = false, + }, + new() + { + FirstName = "Gonzalo", + MiddleName = "Ariel", + LastName = "Montiel", + DateOfBirth = new DateTime(1997, 1, 1, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 4, + Position = Position.RightBack.Text, + AbbrPosition = Position.RightBack.Abbr, + Team = "Nottingham Forest", + League = "Premier League", + Starting11 = false, + }, + new() + { + FirstName = "Germán", + MiddleName = "Alejo", + LastName = "Pezzella", + DateOfBirth = new DateTime(1991, 6, 27, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 6, + Position = Position.CentreBack.Text, + AbbrPosition = Position.CentreBack.Abbr, + Team = "Real Betis Balompié", + League = "La Liga", + Starting11 = false, + }, + new() + { + FirstName = "Marcos", + MiddleName = "Javier", + LastName = "Acuña", + DateOfBirth = new DateTime(1991, 10, 28, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 8, + Position = Position.LeftBack.Text, + AbbrPosition = Position.LeftBack.Abbr, + Team = "Sevilla FC", + League = "La Liga", + Starting11 = false, + }, + new() + { + FirstName = "Lisandro", + LastName = "Martínez", + DateOfBirth = new DateTime(1998, 1, 18, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 25, + Position = Position.CentreBack.Text, + AbbrPosition = Position.CentreBack.Abbr, + Team = "Manchester United", + League = "Premier League", + Starting11 = false, + }, + new() + { + FirstName = "Leandro", + MiddleName = "Daniel", + LastName = "Paredes", + DateOfBirth = new DateTime(1994, 6, 29, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 5, + Position = Position.DefensiveMidfield.Text, + AbbrPosition = Position.DefensiveMidfield.Abbr, + Team = "AS Roma", + League = "Serie A", + Starting11 = false, + }, + new() + { + FirstName = "Exequiel", + MiddleName = "Alejandro", + LastName = "Palacios", + DateOfBirth = new DateTime(1998, 10, 5, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 14, + Position = Position.CentralMidfield.Text, + AbbrPosition = Position.CentralMidfield.Abbr, + Team = "Bayer 04 Leverkusen", + League = "Bundesliga", + Starting11 = false, + }, + new() + { + FirstName = "Alejandro", + MiddleName = "Darío", + LastName = "Gómez", + DateOfBirth = new DateTime(1988, 2, 15, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 17, + Position = Position.LeftWinger.Text, + AbbrPosition = Position.LeftWinger.Abbr, + Team = "AC Monza", + League = "Serie A", + Starting11 = false, + }, + new() + { + FirstName = "Guido", + LastName = "Rodríguez", + DateOfBirth = new DateTime(1994, 4, 12, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 18, + Position = Position.DefensiveMidfield.Text, + AbbrPosition = Position.DefensiveMidfield.Abbr, + Team = "Real Betis Balompié", + League = "La Liga", + Starting11 = false, + }, + new() + { + FirstName = "Ángel", + MiddleName = "Martín", + LastName = "Correa", + DateOfBirth = new DateTime(1995, 3, 9, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 15, + Position = Position.RightWinger.Text, + AbbrPosition = Position.RightWinger.Abbr, + Team = "Atlético Madrid", + League = "La Liga", + Starting11 = false, + }, + new() + { + FirstName = "Thiago", + MiddleName = "Ezequiel", + LastName = "Almada", + DateOfBirth = new DateTime(2001, 4, 26, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 16, + Position = Position.AttackingMidfield.Text, + AbbrPosition = Position.AttackingMidfield.Abbr, + Team = "Atlanta United FC", + League = "Major League Soccer", + Starting11 = false, + }, + new() + { + FirstName = "Paulo", + MiddleName = "Exequiel", + LastName = "Dybala", + DateOfBirth = new DateTime(1993, 11, 15, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 21, + Position = Position.SecondStriker.Text, + AbbrPosition = Position.SecondStriker.Abbr, + Team = "AS Roma", + League = "Serie A", + Starting11 = false, + }, + new() + { + FirstName = "Lautaro", + MiddleName = "Javier", + LastName = "Martínez", + DateOfBirth = new DateTime(1997, 8, 22, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 22, + Position = Position.CentreForward.Text, + AbbrPosition = Position.CentreForward.Abbr, + Team = "Inter Milan", + League = "Serie A", + Starting11 = false, + } + ]; + } + + /// + /// Create a predefined list of 15 substitute players where each player has a fixed GUID identifier and full profile data. + /// + /// A list of 15 Player instances representing substitute players; each entry includes a predefined Id (Guid) and populated fields such as name, date of birth, squad number, position (and abbreviation), team, league, and Starting11 set to false. + public static List GetSubstitutesWithId() + { + return + [ + new() + { + Id = Guid.Parse("b1f8a5d3-2c4e-4a6b-8d9f-1e3c5a7b9d2f"), + FirstName = "Franco", + MiddleName = "Daniel", + LastName = "Armani", + DateOfBirth = new DateTime(1986, 10, 16, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 1, + Position = Position.Goalkeeper.Text, + AbbrPosition = Position.Goalkeeper.Abbr, + Team = "River Plate", + League = "Copa de la Liga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("c2e9b6f4-3d5f-4b7c-9e0a-2f4d6b8c0e3a"), + FirstName = "Gerónimo", + LastName = "Rulli", + DateOfBirth = new DateTime(1992, 5, 20, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 12, + Position = Position.Goalkeeper.Text, + AbbrPosition = Position.Goalkeeper.Abbr, + Team = "Ajax Amsterdam", + League = "Eredivisie", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("d3f0c7e5-4e6a-5c8d-0f1b-3a5e7c9d1f4b"), + FirstName = "Juan", + MiddleName = "Marcos", + LastName = "Foyth", + DateOfBirth = new DateTime(1998, 1, 12, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 2, + Position = Position.RightBack.Text, + AbbrPosition = Position.RightBack.Abbr, + Team = "Villarreal", + League = "La Liga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("e4a1d8f6-5f7b-6d9e-1a2c-4b6d8e0a2c5d"), + FirstName = "Gonzalo", + MiddleName = "Ariel", + LastName = "Montiel", + DateOfBirth = new DateTime(1997, 1, 1, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 4, + Position = Position.RightBack.Text, + AbbrPosition = Position.RightBack.Abbr, + Team = "Nottingham Forest", + League = "Premier League", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("f5b2e9a7-6a8c-7e0f-2b3d-5c7e9a1b3d6e"), + FirstName = "Germán", + MiddleName = "Alejo", + LastName = "Pezzella", + DateOfBirth = new DateTime(1991, 6, 27, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 6, + Position = Position.CentreBack.Text, + AbbrPosition = Position.CentreBack.Abbr, + Team = "Real Betis Balompié", + League = "La Liga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("a6c3f0b8-7b9d-8f1a-3c4e-6d8f0b2c4e7f"), + FirstName = "Marcos", + MiddleName = "Javier", + LastName = "Acuña", + DateOfBirth = new DateTime(1991, 10, 28, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 8, + Position = Position.LeftBack.Text, + AbbrPosition = Position.LeftBack.Abbr, + Team = "Sevilla FC", + League = "La Liga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("b7d4a1c9-8c0e-9a2b-4d5f-7e9a1c3d5f8a"), + FirstName = "Lisandro", + LastName = "Martínez", + DateOfBirth = new DateTime(1998, 1, 18, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 25, + Position = Position.CentreBack.Text, + AbbrPosition = Position.CentreBack.Abbr, + Team = "Manchester United", + League = "Premier League", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("c8e5b2d0-9d1f-0b3c-5e6a-8f0b2d4e6a9b"), + FirstName = "Leandro", + MiddleName = "Daniel", + LastName = "Paredes", + DateOfBirth = new DateTime(1994, 6, 29, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 5, + Position = Position.DefensiveMidfield.Text, + AbbrPosition = Position.DefensiveMidfield.Abbr, + Team = "AS Roma", + League = "Serie A", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("d9f6c3e1-0e2a-1c4d-6f7b-9a1c3e5f7b0c"), + FirstName = "Exequiel", + MiddleName = "Alejandro", + LastName = "Palacios", + DateOfBirth = new DateTime(1998, 10, 5, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 14, + Position = Position.CentralMidfield.Text, + AbbrPosition = Position.CentralMidfield.Abbr, + Team = "Bayer 04 Leverkusen", + League = "Bundesliga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("e0a7d4f2-1f3b-2d5e-7a8c-0b2d4f6a8c1d"), + FirstName = "Alejandro", + MiddleName = "Darío", + LastName = "Gómez", + DateOfBirth = new DateTime(1988, 2, 15, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 17, + Position = Position.LeftWinger.Text, + AbbrPosition = Position.LeftWinger.Abbr, + Team = "AC Monza", + League = "Serie A", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("f1b8e5a3-2a4c-3e6f-8b9d-1c3e5a7b9d2e"), + FirstName = "Guido", + LastName = "Rodríguez", + DateOfBirth = new DateTime(1994, 4, 12, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 18, + Position = Position.DefensiveMidfield.Text, + AbbrPosition = Position.DefensiveMidfield.Abbr, + Team = "Real Betis Balompié", + League = "La Liga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("a2c9f6b4-3b5d-4f7a-9c0e-2d4f6b8c0e3f"), + FirstName = "Ángel", + MiddleName = "Martín", + LastName = "Correa", + DateOfBirth = new DateTime(1995, 3, 9, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 15, + Position = Position.RightWinger.Text, + AbbrPosition = Position.RightWinger.Abbr, + Team = "Atlético Madrid", + League = "La Liga", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("b3d0a7c5-4c6e-5a8b-0d1f-3e5a7c9d1f4a"), + FirstName = "Thiago", + MiddleName = "Ezequiel", + LastName = "Almada", + DateOfBirth = new DateTime(2001, 4, 26, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 16, + Position = Position.AttackingMidfield.Text, + AbbrPosition = Position.AttackingMidfield.Abbr, + Team = "Atlanta United FC", + League = "Major League Soccer", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("c4e1b8d6-5d7f-6b9c-1e2a-4f6d8e0a2c5b"), + FirstName = "Paulo", + MiddleName = "Exequiel", + LastName = "Dybala", + DateOfBirth = new DateTime(1993, 11, 15, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 21, + Position = Position.SecondStriker.Text, + AbbrPosition = Position.SecondStriker.Abbr, + Team = "AS Roma", + League = "Serie A", + Starting11 = false, + }, + new() + { + Id = Guid.Parse("d5f2c9e7-6e8a-7c0d-2f3b-5a7e9a1b3d6c"), + FirstName = "Lautaro", + MiddleName = "Javier", + LastName = "Martínez", + DateOfBirth = new DateTime(1997, 8, 22, 0, 0, 0, DateTimeKind.Utc), + SquadNumber = 22, + Position = Position.CentreForward.Text, + AbbrPosition = Position.CentreForward.Abbr, + Team = "Inter Milan", + League = "Serie A", + Starting11 = false, + } + ]; + } + /// /// The purpose of this method is to demonstrate the capabilities of /// System.Text.Json.JsonSerializer diff --git a/src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db b/src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db index c3208ad..9d38e8c 100644 Binary files a/src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db and b/src/Dotnet.Samples.AspNetCore.WebApi/storage/players-sqlite3.db differ