diff --git a/Directory.Build.targets b/Directory.Build.targets index 45566edda..75f5805db 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -43,6 +43,7 @@ + diff --git a/MORYX-Framework.sln b/MORYX-Framework.sln index 144390c6e..2699ff6e8 100644 --- a/MORYX-Framework.sln +++ b/MORYX-Framework.sln @@ -123,6 +123,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moryx.TestTools.NUnit", "sr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moryx.TestTools.IntegrationTest", "src\Moryx.TestTools.IntegrationTest\Moryx.TestTools.IntegrationTest.csproj", "{C949164C-0345-4893-9E4C-A79BC1F93F85}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moryx.Model.SqlServer", "src\Moryx.Model.SqlServer\Moryx.Model.SqlServer.csproj", "{4402EF2E-CBA8-4EEF-B8A6-EC8364960306}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -309,6 +311,10 @@ Global {C949164C-0345-4893-9E4C-A79BC1F93F85}.Debug|Any CPU.Build.0 = Debug|Any CPU {C949164C-0345-4893-9E4C-A79BC1F93F85}.Release|Any CPU.ActiveCfg = Release|Any CPU {C949164C-0345-4893-9E4C-A79BC1F93F85}.Release|Any CPU.Build.0 = Release|Any CPU + {4402EF2E-CBA8-4EEF-B8A6-EC8364960306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4402EF2E-CBA8-4EEF-B8A6-EC8364960306}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4402EF2E-CBA8-4EEF-B8A6-EC8364960306}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4402EF2E-CBA8-4EEF-B8A6-EC8364960306}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -355,10 +361,11 @@ Global {4FFB98A7-9A4C-476F-8BCC-C19B7F757BF8} = {8517D209-5BC1-47BD-A7C7-9CF9ADD9F5B6} {6FF878E0-AF61-4C3A-9B9C-71C35A949E51} = {953AAE25-26C8-4A28-AB08-61BAFE41B22F} {C949164C-0345-4893-9E4C-A79BC1F93F85} = {953AAE25-26C8-4A28-AB08-61BAFE41B22F} + {4402EF2E-CBA8-4EEF-B8A6-EC8364960306} = {74112169-6672-4907-A187-F055111940A9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {36EFC961-F4E7-49DC-A36A-99594FFB8243} + SolutionGuid = {36EFC961-F4E7-49DC-A36A-99594FFB8243} RESX_TaskErrorCategory = Message - RESX_ShowErrorsInErrorList = True + RESX_ShowErrorsInErrorList = True EndGlobalSection EndGlobal diff --git a/src/Moryx.Model.PostgreSQL/Attributes/NpgsqlDatabaseContextAttribute.cs b/src/Moryx.Model.PostgreSQL/Attributes/NpgsqlDatabaseContextAttribute.cs index 0f4629f51..c6e764b44 100644 --- a/src/Moryx.Model.PostgreSQL/Attributes/NpgsqlDatabaseContextAttribute.cs +++ b/src/Moryx.Model.PostgreSQL/Attributes/NpgsqlDatabaseContextAttribute.cs @@ -10,5 +10,8 @@ namespace Moryx.Model.PostgreSQL.Attributes /// Attribute to identify Npgsql specific contexts /// [AttributeUsage(AttributeTargets.Class)] - public class NpgsqlDatabaseContextAttribute : DatabaseSpecificContextAttribute { } + public class NpgsqlDatabaseContextAttribute : DatabaseSpecificContextAttribute + { + + } } diff --git a/src/Moryx.Model.SqlServer/Moryx.Model.SqlServer.csproj b/src/Moryx.Model.SqlServer/Moryx.Model.SqlServer.csproj new file mode 100644 index 000000000..fe5b66a77 --- /dev/null +++ b/src/Moryx.Model.SqlServer/Moryx.Model.SqlServer.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + true + Adapter for Moryx.Model on SqlServer + MORYX;Entity;Framework;EntityFramework;DataModel;Model;Database;SqlServer + true + + + + + + + + + + diff --git a/src/Moryx.Model.SqlServer/SqlServerDatabaseConfig.cs b/src/Moryx.Model.SqlServer/SqlServerDatabaseConfig.cs new file mode 100644 index 000000000..87b2af221 --- /dev/null +++ b/src/Moryx.Model.SqlServer/SqlServerDatabaseConfig.cs @@ -0,0 +1,46 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Runtime.Serialization; + +namespace Moryx.Model.SqlServer; + +/// +/// Database config for the SqlServer databases +/// +[DataContract] +public class SqlServerDatabaseConfig : DatabaseConfig +{ + /// + /// Creates a new instance of the + /// + public SqlServerDatabaseConfig() + { + ConnectionSettings = new SqlServerDatabaseConnectionSettings(); + ConfiguratorTypename = typeof(SqlServerModelConfigurator).AssemblyQualifiedName; + } +} + +/// +/// Database connection settings for the SqlServer databases +/// +public class SqlServerDatabaseConnectionSettings : DatabaseConnectionSettings +{ + private string _database; + + /// + [DataMember] + public override string Database + { + get => _database; + set + { + if (string.IsNullOrEmpty(value)) return; + _database = value; + ConnectionString = ConnectionString?.Replace("", value); + } + } + + /// + [DataMember, Required, DefaultValue("Server=localhost;Initial Catalog=;User Id=sa;Password=password;TrustServerCertificate=True;")] + public override string ConnectionString { get; set; } +} \ No newline at end of file diff --git a/src/Moryx.Model.SqlServer/SqlServerDatabaseContextAttribute.cs b/src/Moryx.Model.SqlServer/SqlServerDatabaseContextAttribute.cs new file mode 100644 index 000000000..7a1e964bc --- /dev/null +++ b/src/Moryx.Model.SqlServer/SqlServerDatabaseContextAttribute.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2023, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using System; +using Moryx.Model.Attributes; + +namespace Moryx.Model.SqlServer; + +/// +/// Attribute to identify SqlServer specific contexts +/// +[AttributeUsage(AttributeTargets.Class)] +public class SqlServerDatabaseContextAttribute : DatabaseSpecificContextAttribute +{ + +} \ No newline at end of file diff --git a/src/Moryx.Model.SqlServer/SqlServerModelConfigurator.cs b/src/Moryx.Model.SqlServer/SqlServerModelConfigurator.cs new file mode 100644 index 000000000..310ca0418 --- /dev/null +++ b/src/Moryx.Model.SqlServer/SqlServerModelConfigurator.cs @@ -0,0 +1,161 @@ +// Copyright (c) 2025, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Moryx.Model.Configuration; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data.Common; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace Moryx.Model.SqlServer; + +/// +/// Used to configure, create and update data models +/// +[DisplayName("SqlServer Connector")] +public sealed class SqlServerModelConfigurator : ModelConfiguratorBase +{ + /// + protected override DbConnection CreateConnection(IDatabaseConfig config) + { + return CreateConnection(config, true); + } + + /// + protected override DbConnection CreateConnection(IDatabaseConfig config, bool includeModel) + { + return new SqlConnection(BuildConnectionString(config, includeModel)); + } + + /// + protected override DbCommand CreateCommand(string cmdText, DbConnection connection) + { + return new SqlCommand(cmdText, (SqlConnection)connection); + } + + /// + public override async Task DeleteDatabase(IDatabaseConfig config) + { + var settings = (SqlServerDatabaseConnectionSettings)config.ConnectionSettings; + + // Create connection and prepare command + await using var connection = new SqlConnection(BuildConnectionString(config, false)); + + var sqlCommandText = $"ALTER DATABASE {settings.Database} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;" + + $"DROP DATABASE [{settings.Database}]"; + + await using var command = CreateCommand(sqlCommandText, connection); + + // Open connection + await connection.OpenAsync(); + await command.ExecuteNonQueryAsync(); + } + + /// + public override async Task DumpDatabase(IDatabaseConfig config, string targetPath) + { + if (!IsValidBackupFilePath(targetPath)) + throw new ArgumentException("Invalid backup file path."); + + var connectionString = CreateConnectionStringBuilder(config); + + var dumpName = $"{DateTime.Now:dd-MM-yyyy-hh-mm-ss}_{connectionString.InitialCatalog}.bak"; + var fileName = Path.Combine(targetPath, dumpName); + + await using var connection = new SqlConnection(BuildConnectionString(config, false)); + await using var command = + CreateCommand($"BACKUP DATABASE [{connectionString.InitialCatalog}] TO DISK = N'{fileName}' WITH INIT", + connection); + + Logger.Log(LogLevel.Debug, "Starting to dump database with 'BACKUP DATABASE' to: {fileName}", fileName); + + await connection.OpenAsync(); + await command.ExecuteNonQueryAsync(); + } + + private static SqlConnectionStringBuilder CreateConnectionStringBuilder(IDatabaseConfig config, bool includeModel = true) + { + var builder = new SqlConnectionStringBuilder(config.ConnectionSettings.ConnectionString) + { + InitialCatalog = includeModel ? config.ConnectionSettings.Database : string.Empty + }; + + return builder; + } + + /// + public override async Task RestoreDatabase(IDatabaseConfig config, string filePath) + { + if (!IsValidBackupFilePath(filePath)) + throw new ArgumentException("Invalid backup file path."); + + var connectionString = CreateConnectionStringBuilder(config); + + await using var connection = new SqlConnection(BuildConnectionString(config, false)); + await using var command = CreateCommand($"RESTORE DATABASE [{connectionString.InitialCatalog}] FROM DISK = N'{filePath}' WITH REPLACE", + connection); + + Logger.Log(LogLevel.Debug, "Starting to restore database with 'RESTORE DATABASE' from: {filePath}", filePath); + + await connection.OpenAsync(); + await command.ExecuteNonQueryAsync(); + } + + /// + public override DbContextOptions BuildDbContextOptions(IDatabaseConfig config) + { + var builder = new DbContextOptionsBuilder(); + builder.UseSqlServer(BuildConnectionString(config, true)); + + return builder.Options; + } + + private static string BuildConnectionString(IDatabaseConfig config, bool includeModel) + { + if (!IsValidDatabaseName(config.ConnectionSettings.Database)) + throw new ArgumentException("Invalid database name."); + + var builder = CreateConnectionStringBuilder(config, includeModel); + builder.PersistSecurityInfo = true; + + return builder.ToString(); + } + + /// + protected override DbContext CreateMigrationContext(IDatabaseConfig config) + { + var migrationAssemblyType = FindMigrationAssemblyType(typeof(SqlServerDatabaseContextAttribute)); + + var builder = new DbContextOptionsBuilder(); + builder.UseSqlServer( + BuildConnectionString(config, true), + x => x.MigrationsAssembly(migrationAssemblyType.Assembly.FullName)); + + return CreateContext(migrationAssemblyType, builder.Options); + } + + private static bool IsValidDatabaseName(string dbName) + { + // Avoid sql injection by validating the database name + if (string.IsNullOrWhiteSpace(dbName) || dbName.Length > 128) + return false; + + // Only allow letters, numbers, and underscores + return Regex.IsMatch(dbName, @"^[A-Za-z0-9_]+$"); + } + + private static bool IsValidBackupFilePath(string filePath) + { + // Disallow dangerous characters + var invalidStrings = new[] { ";", "'", "\"", "--" }; + return invalidStrings.All(s => !filePath.Contains(s)); + } +} \ No newline at end of file diff --git a/src/Moryx.Model.Sqlite/SqliteDatabaseConfig.cs b/src/Moryx.Model.Sqlite/SqliteDatabaseConfig.cs index 400d22660..26ceb5776 100644 --- a/src/Moryx.Model.Sqlite/SqliteDatabaseConfig.cs +++ b/src/Moryx.Model.Sqlite/SqliteDatabaseConfig.cs @@ -25,7 +25,16 @@ public SqliteDatabaseConfig() ConfiguratorTypename = typeof(SqliteModelConfigurator).AssemblyQualifiedName; } } - + + internal class DefaultSqliteConnectionStringAttribute : DefaultValueAttribute + { + public DefaultSqliteConnectionStringAttribute() : base("") + { + var path = Path.Combine(".", "db", ".db"); + SetValue($"Data Source={path};Mode=ReadWrite;"); + } + } + /// /// Database connection settings for the Sqlite databases /// @@ -33,15 +42,6 @@ public class SqliteDatabaseConnectionSettings : DatabaseConnectionSettings { private string _database; - /// - /// Default constructor of - /// - public SqliteDatabaseConnectionSettings() - { - var defaultDbPath = Path.Combine(".", "db", ".db"); - ConnectionString = $"Data Source={defaultDbPath};Mode=ReadWrite;"; - } - /// [DataMember] public override string Database @@ -56,7 +56,7 @@ public override string Database } /// - [DataMember, Required] + [DataMember, Required, DefaultSqliteConnectionString] public override string ConnectionString { get; set; } /// diff --git a/src/Moryx.Model/Attributes/SqliteContextAttribute.cs b/src/Moryx.Model/Attributes/DatabaseSpecificContextAttribute.cs similarity index 78% rename from src/Moryx.Model/Attributes/SqliteContextAttribute.cs rename to src/Moryx.Model/Attributes/DatabaseSpecificContextAttribute.cs index 70e0d5d05..fc5800828 100644 --- a/src/Moryx.Model/Attributes/SqliteContextAttribute.cs +++ b/src/Moryx.Model/Attributes/DatabaseSpecificContextAttribute.cs @@ -9,5 +9,8 @@ namespace Moryx.Model.Attributes /// Attribute to identify database specific contexts /// [AttributeUsage(AttributeTargets.Class)] - public class DatabaseSpecificContextAttribute : Attribute { } + public class DatabaseSpecificContextAttribute : Attribute + { + + } } diff --git a/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs b/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs index 157908e89..ecf6a5046 100644 --- a/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs +++ b/src/Moryx.Model/Configuration/ModelConfiguratorBase.cs @@ -274,7 +274,7 @@ private async Task TestDatabaseConnection(IDatabaseConfig config) await conn.OpenAsync(); return true; } - catch(Exception) + catch(Exception e) { return false; } diff --git a/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj b/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj index 417a392b3..d5458a046 100644 --- a/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj +++ b/src/Moryx.Resources.Management/Moryx.Resources.Management.csproj @@ -3,18 +3,18 @@ net8.0 true - true + true ResourceManagement module composing and maintaining the resource graph as the habitat for digital twins of manufacturing assets. MORYX;IIoT;IoT;Manufacturing;API;Resource - true + true - - + + diff --git a/src/Moryx.TestTools.Test.Model/Migrations/20210901104117_InitialCreate.cs b/src/Moryx.TestTools.Test.Model/Migrations/20210901104117_InitialCreate.cs deleted file mode 100644 index c1ae27fff..000000000 --- a/src/Moryx.TestTools.Test.Model/Migrations/20210901104117_InitialCreate.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Moryx.TestTools.Test.Model.Migrations -{ - public partial class InitialCreate : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.EnsureSchema( - name: "public"); - - migrationBuilder.CreateTable( - name: "Cars", - schema: "public", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Created = table.Column(nullable: false), - Updated = table.Column(nullable: false), - Deleted = table.Column(nullable: true), - Name = table.Column(nullable: true), - Price = table.Column(nullable: false), - Image = table.Column(nullable: true), - Discriminator = table.Column(nullable: false), - Performance = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Cars", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Houses", - schema: "public", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Created = table.Column(nullable: false), - Updated = table.Column(nullable: false), - Deleted = table.Column(nullable: true), - Name = table.Column(nullable: true), - Size = table.Column(nullable: false), - IsMethLabratory = table.Column(nullable: false), - IsBurnedDown = table.Column(nullable: false), - ToRent = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Houses", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HugePocos", - schema: "public", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Float1 = table.Column(nullable: false), - Name1 = table.Column(nullable: true), - Number1 = table.Column(nullable: false), - Float2 = table.Column(nullable: false), - Name2 = table.Column(nullable: true), - Number2 = table.Column(nullable: false), - Float3 = table.Column(nullable: false), - Name3 = table.Column(nullable: true), - Number3 = table.Column(nullable: false), - Float4 = table.Column(nullable: false), - Name4 = table.Column(nullable: true), - Number4 = table.Column(nullable: false), - Float5 = table.Column(nullable: false), - Name5 = table.Column(nullable: true), - Number5 = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HugePocos", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Jsons", - schema: "public", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - JsonData = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Jsons", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Wheels", - schema: "public", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - CarId = table.Column(nullable: true), - WheelType = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Wheels", x => x.Id); - table.ForeignKey( - name: "FK_Wheels_Cars_CarId", - column: x => x.CarId, - principalSchema: "public", - principalTable: "Cars", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateIndex( - name: "IX_Wheels_CarId", - schema: "public", - table: "Wheels", - column: "CarId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Houses", - schema: "public"); - - migrationBuilder.DropTable( - name: "HugePocos", - schema: "public"); - - migrationBuilder.DropTable( - name: "Jsons", - schema: "public"); - - migrationBuilder.DropTable( - name: "Wheels", - schema: "public"); - - migrationBuilder.DropTable( - name: "Cars", - schema: "public"); - } - } -} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/20210901104117_InitialCreate.Designer.cs b/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/20251030141744_InitialCreate.Designer.cs similarity index 69% rename from src/Moryx.TestTools.Test.Model/Migrations/20210901104117_InitialCreate.Designer.cs rename to src/Moryx.TestTools.Test.Model/Migrations/Npgsql/20251030141744_InitialCreate.Designer.cs index f77c3efd2..2caecee12 100644 --- a/src/Moryx.TestTools.Test.Model/Migrations/20210901104117_InitialCreate.Designer.cs +++ b/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/20251030141744_InitialCreate.Designer.cs @@ -7,37 +7,46 @@ using Moryx.TestTools.Test.Model; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace Moryx.TestTools.Test.Model.Migrations +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.Npgsql { - [DbContext(typeof(TestModelContext))] - [Migration("20210901104117_InitialCreate")] + [DbContext(typeof(NpgsqlTestModelContext))] + [Migration("20251030141744_InitialCreate")] partial class InitialCreate { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasDefaultSchema("public") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.0") + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) .HasAnnotation("Relational:MaxIdentifierLength", 63); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Created") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("Deleted") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("Discriminator") .IsRequired() - .HasColumnType("text"); + .HasMaxLength(21) + .HasColumnType("character varying(21)"); b.Property("Image") .HasColumnType("bytea"); @@ -48,28 +57,37 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Price") .HasColumnType("integer"); + b.Property("ReleaseDateLocal") + .HasColumnType("timestamp with time zone"); + + b.Property("ReleaseDateUtc") + .HasColumnType("timestamp with time zone"); + b.Property("Updated") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.HasKey("Id"); - b.ToTable("Cars"); + b.ToTable("Cars", "public"); b.HasDiscriminator("Discriminator").HasValue("CarEntity"); + + b.UseTphMappingStrategy(); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.HouseEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Created") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("Deleted") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("IsBurnedDown") .HasColumnType("boolean"); @@ -87,19 +105,20 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .HasColumnType("boolean"); b.Property("Updated") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.HasKey("Id"); - b.ToTable("Houses"); + b.ToTable("Houses", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.HugePocoEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Float1") .HasColumnType("double precision"); @@ -148,30 +167,32 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("HugePocos"); + b.ToTable("HugePocos", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.JsonEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("JsonData") .HasColumnType("text"); b.HasKey("Id"); - b.ToTable("Jsons"); + b.ToTable("Jsons", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("CarId") .HasColumnType("bigint"); @@ -183,7 +204,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasIndex("CarId"); - b.ToTable("Wheels"); + b.ToTable("Wheels", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.SportCarEntity", b => @@ -201,6 +222,13 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasOne("Moryx.TestTools.Test.Model.CarEntity", "Car") .WithMany("Wheels") .HasForeignKey("CarId"); + + b.Navigation("Car"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Navigation("Wheels"); }); #pragma warning restore 612, 618 } diff --git a/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/20251030141744_InitialCreate.cs b/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/20251030141744_InitialCreate.cs new file mode 100644 index 000000000..d9fe168cf --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/20251030141744_InitialCreate.cs @@ -0,0 +1,156 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.Npgsql +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "public"); + + migrationBuilder.CreateTable( + name: "Cars", + schema: "public", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: true), + Price = table.Column(type: "integer", nullable: false), + Image = table.Column(type: "bytea", nullable: true), + ReleaseDateLocal = table.Column(type: "timestamp with time zone", nullable: false), + ReleaseDateUtc = table.Column(type: "timestamp with time zone", nullable: false), + Discriminator = table.Column(type: "character varying(21)", maxLength: 21, nullable: false), + Performance = table.Column(type: "integer", nullable: true), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Updated = table.Column(type: "timestamp with time zone", nullable: false), + Deleted = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Cars", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Houses", + schema: "public", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: true), + Size = table.Column(type: "integer", nullable: false), + IsMethLabratory = table.Column(type: "boolean", nullable: false), + IsBurnedDown = table.Column(type: "boolean", nullable: false), + ToRent = table.Column(type: "boolean", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Updated = table.Column(type: "timestamp with time zone", nullable: false), + Deleted = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Houses", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "HugePocos", + schema: "public", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Float1 = table.Column(type: "double precision", nullable: false), + Name1 = table.Column(type: "text", nullable: true), + Number1 = table.Column(type: "integer", nullable: false), + Float2 = table.Column(type: "double precision", nullable: false), + Name2 = table.Column(type: "text", nullable: true), + Number2 = table.Column(type: "integer", nullable: false), + Float3 = table.Column(type: "double precision", nullable: false), + Name3 = table.Column(type: "text", nullable: true), + Number3 = table.Column(type: "integer", nullable: false), + Float4 = table.Column(type: "double precision", nullable: false), + Name4 = table.Column(type: "text", nullable: true), + Number4 = table.Column(type: "integer", nullable: false), + Float5 = table.Column(type: "double precision", nullable: false), + Name5 = table.Column(type: "text", nullable: true), + Number5 = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_HugePocos", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Jsons", + schema: "public", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + JsonData = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Jsons", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Wheels", + schema: "public", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + CarId = table.Column(type: "bigint", nullable: true), + WheelType = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Wheels", x => x.Id); + table.ForeignKey( + name: "FK_Wheels_Cars_CarId", + column: x => x.CarId, + principalSchema: "public", + principalTable: "Cars", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Wheels_CarId", + schema: "public", + table: "Wheels", + column: "CarId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Houses", + schema: "public"); + + migrationBuilder.DropTable( + name: "HugePocos", + schema: "public"); + + migrationBuilder.DropTable( + name: "Jsons", + schema: "public"); + + migrationBuilder.DropTable( + name: "Wheels", + schema: "public"); + + migrationBuilder.DropTable( + name: "Cars", + schema: "public"); + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/TestModelContextModelSnapshot.cs b/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/NpgsqlTestModelContextModelSnapshot.cs similarity index 68% rename from src/Moryx.TestTools.Test.Model/Migrations/TestModelContextModelSnapshot.cs rename to src/Moryx.TestTools.Test.Model/Migrations/Npgsql/NpgsqlTestModelContextModelSnapshot.cs index a9e73c24f..74d0b0350 100644 --- a/src/Moryx.TestTools.Test.Model/Migrations/TestModelContextModelSnapshot.cs +++ b/src/Moryx.TestTools.Test.Model/Migrations/Npgsql/NpgsqlTestModelContextModelSnapshot.cs @@ -6,36 +6,44 @@ using Moryx.TestTools.Test.Model; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -namespace Moryx.TestTools.Test.Model.Migrations +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.Npgsql { - [DbContext(typeof(TestModelContext))] - partial class TestModelContextModelSnapshot : ModelSnapshot + [DbContext(typeof(NpgsqlTestModelContext))] + partial class NpgsqlTestModelContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasDefaultSchema("public") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.0") + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) .HasAnnotation("Relational:MaxIdentifierLength", 63); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Created") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("Deleted") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("Discriminator") .IsRequired() - .HasColumnType("text"); + .HasMaxLength(21) + .HasColumnType("character varying(21)"); b.Property("Image") .HasColumnType("bytea"); @@ -46,28 +54,37 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Price") .HasColumnType("integer"); + b.Property("ReleaseDateLocal") + .HasColumnType("timestamp with time zone"); + + b.Property("ReleaseDateUtc") + .HasColumnType("timestamp with time zone"); + b.Property("Updated") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.HasKey("Id"); - b.ToTable("Cars"); + b.ToTable("Cars", "public"); b.HasDiscriminator("Discriminator").HasValue("CarEntity"); + + b.UseTphMappingStrategy(); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.HouseEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Created") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("Deleted") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.Property("IsBurnedDown") .HasColumnType("boolean"); @@ -85,19 +102,20 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("boolean"); b.Property("Updated") - .HasColumnType("timestamp without time zone"); + .HasColumnType("timestamp with time zone"); b.HasKey("Id"); - b.ToTable("Houses"); + b.ToTable("Houses", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.HugePocoEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Float1") .HasColumnType("double precision"); @@ -146,30 +164,32 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("HugePocos"); + b.ToTable("HugePocos", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.JsonEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("JsonData") .HasColumnType("text"); b.HasKey("Id"); - b.ToTable("Jsons"); + b.ToTable("Jsons", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("CarId") .HasColumnType("bigint"); @@ -181,7 +201,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("CarId"); - b.ToTable("Wheels"); + b.ToTable("Wheels", "public"); }); modelBuilder.Entity("Moryx.TestTools.Test.Model.SportCarEntity", b => @@ -199,6 +219,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("Moryx.TestTools.Test.Model.CarEntity", "Car") .WithMany("Wheels") .HasForeignKey("CarId"); + + b.Navigation("Car"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Navigation("Wheels"); }); #pragma warning restore 612, 618 } diff --git a/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/20251030141638_InitialCreate.Designer.cs b/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/20251030141638_InitialCreate.Designer.cs new file mode 100644 index 000000000..9cb35fdd9 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/20251030141638_InitialCreate.Designer.cs @@ -0,0 +1,233 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moryx.Resources.Model; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.SqlServer +{ + [DbContext(typeof(SqlServerTestModelContext))] + [Migration("20251030141638_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("resources") + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("datetime2"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("nvarchar(21)"); + + b.Property("Image") + .HasColumnType("varbinary(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("ReleaseDateLocal") + .HasColumnType("datetime2"); + + b.Property("ReleaseDateUtc") + .HasColumnType("datetime2"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Cars", "resources"); + + b.HasDiscriminator("Discriminator").HasValue("CarEntity"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HouseEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("datetime2"); + + b.Property("IsBurnedDown") + .HasColumnType("bit"); + + b.Property("IsMethLabratory") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Size") + .HasColumnType("int"); + + b.Property("ToRent") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Houses", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HugePocoEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Float1") + .HasColumnType("float"); + + b.Property("Float2") + .HasColumnType("float"); + + b.Property("Float3") + .HasColumnType("float"); + + b.Property("Float4") + .HasColumnType("float"); + + b.Property("Float5") + .HasColumnType("float"); + + b.Property("Name1") + .HasColumnType("nvarchar(max)"); + + b.Property("Name2") + .HasColumnType("nvarchar(max)"); + + b.Property("Name3") + .HasColumnType("nvarchar(max)"); + + b.Property("Name4") + .HasColumnType("nvarchar(max)"); + + b.Property("Name5") + .HasColumnType("nvarchar(max)"); + + b.Property("Number1") + .HasColumnType("int"); + + b.Property("Number2") + .HasColumnType("int"); + + b.Property("Number3") + .HasColumnType("int"); + + b.Property("Number4") + .HasColumnType("int"); + + b.Property("Number5") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("HugePocos", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.JsonEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("JsonData") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Jsons", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CarId") + .HasColumnType("bigint"); + + b.Property("WheelType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CarId"); + + b.ToTable("Wheels", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.SportCarEntity", b => + { + b.HasBaseType("Moryx.TestTools.Test.Model.CarEntity"); + + b.Property("Performance") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("SportCarEntity"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.HasOne("Moryx.TestTools.Test.Model.CarEntity", "Car") + .WithMany("Wheels") + .HasForeignKey("CarId"); + + b.Navigation("Car"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Navigation("Wheels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/20251030141638_InitialCreate.cs b/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/20251030141638_InitialCreate.cs new file mode 100644 index 000000000..ff2e1bb50 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/20251030141638_InitialCreate.cs @@ -0,0 +1,155 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.SqlServer +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "resources"); + + migrationBuilder.CreateTable( + name: "Cars", + schema: "resources", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: true), + Price = table.Column(type: "int", nullable: false), + Image = table.Column(type: "varbinary(max)", nullable: true), + ReleaseDateLocal = table.Column(type: "datetime2", nullable: false), + ReleaseDateUtc = table.Column(type: "datetime2", nullable: false), + Discriminator = table.Column(type: "nvarchar(21)", maxLength: 21, nullable: false), + Performance = table.Column(type: "int", nullable: true), + Created = table.Column(type: "datetime2", nullable: false), + Updated = table.Column(type: "datetime2", nullable: false), + Deleted = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Cars", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Houses", + schema: "resources", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: true), + Size = table.Column(type: "int", nullable: false), + IsMethLabratory = table.Column(type: "bit", nullable: false), + IsBurnedDown = table.Column(type: "bit", nullable: false), + ToRent = table.Column(type: "bit", nullable: false), + Created = table.Column(type: "datetime2", nullable: false), + Updated = table.Column(type: "datetime2", nullable: false), + Deleted = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Houses", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "HugePocos", + schema: "resources", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Float1 = table.Column(type: "float", nullable: false), + Name1 = table.Column(type: "nvarchar(max)", nullable: true), + Number1 = table.Column(type: "int", nullable: false), + Float2 = table.Column(type: "float", nullable: false), + Name2 = table.Column(type: "nvarchar(max)", nullable: true), + Number2 = table.Column(type: "int", nullable: false), + Float3 = table.Column(type: "float", nullable: false), + Name3 = table.Column(type: "nvarchar(max)", nullable: true), + Number3 = table.Column(type: "int", nullable: false), + Float4 = table.Column(type: "float", nullable: false), + Name4 = table.Column(type: "nvarchar(max)", nullable: true), + Number4 = table.Column(type: "int", nullable: false), + Float5 = table.Column(type: "float", nullable: false), + Name5 = table.Column(type: "nvarchar(max)", nullable: true), + Number5 = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_HugePocos", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Jsons", + schema: "resources", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + JsonData = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Jsons", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Wheels", + schema: "resources", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CarId = table.Column(type: "bigint", nullable: true), + WheelType = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Wheels", x => x.Id); + table.ForeignKey( + name: "FK_Wheels_Cars_CarId", + column: x => x.CarId, + principalSchema: "resources", + principalTable: "Cars", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Wheels_CarId", + schema: "resources", + table: "Wheels", + column: "CarId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Houses", + schema: "resources"); + + migrationBuilder.DropTable( + name: "HugePocos", + schema: "resources"); + + migrationBuilder.DropTable( + name: "Jsons", + schema: "resources"); + + migrationBuilder.DropTable( + name: "Wheels", + schema: "resources"); + + migrationBuilder.DropTable( + name: "Cars", + schema: "resources"); + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/SqlServerTestModelContextModelSnapshot.cs b/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/SqlServerTestModelContextModelSnapshot.cs new file mode 100644 index 000000000..9861ae999 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/SqlServer/SqlServerTestModelContextModelSnapshot.cs @@ -0,0 +1,230 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moryx.Resources.Model; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.SqlServer +{ + [DbContext(typeof(SqlServerTestModelContext))] + partial class SqlServerTestModelContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("resources") + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("datetime2"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("nvarchar(21)"); + + b.Property("Image") + .HasColumnType("varbinary(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Price") + .HasColumnType("int"); + + b.Property("ReleaseDateLocal") + .HasColumnType("datetime2"); + + b.Property("ReleaseDateUtc") + .HasColumnType("datetime2"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Cars", "resources"); + + b.HasDiscriminator("Discriminator").HasValue("CarEntity"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HouseEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("datetime2"); + + b.Property("IsBurnedDown") + .HasColumnType("bit"); + + b.Property("IsMethLabratory") + .HasColumnType("bit"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Size") + .HasColumnType("int"); + + b.Property("ToRent") + .HasColumnType("bit"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Houses", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HugePocoEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Float1") + .HasColumnType("float"); + + b.Property("Float2") + .HasColumnType("float"); + + b.Property("Float3") + .HasColumnType("float"); + + b.Property("Float4") + .HasColumnType("float"); + + b.Property("Float5") + .HasColumnType("float"); + + b.Property("Name1") + .HasColumnType("nvarchar(max)"); + + b.Property("Name2") + .HasColumnType("nvarchar(max)"); + + b.Property("Name3") + .HasColumnType("nvarchar(max)"); + + b.Property("Name4") + .HasColumnType("nvarchar(max)"); + + b.Property("Name5") + .HasColumnType("nvarchar(max)"); + + b.Property("Number1") + .HasColumnType("int"); + + b.Property("Number2") + .HasColumnType("int"); + + b.Property("Number3") + .HasColumnType("int"); + + b.Property("Number4") + .HasColumnType("int"); + + b.Property("Number5") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("HugePocos", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.JsonEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("JsonData") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Jsons", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CarId") + .HasColumnType("bigint"); + + b.Property("WheelType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CarId"); + + b.ToTable("Wheels", "resources"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.SportCarEntity", b => + { + b.HasBaseType("Moryx.TestTools.Test.Model.CarEntity"); + + b.Property("Performance") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("SportCarEntity"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.HasOne("Moryx.TestTools.Test.Model.CarEntity", "Car") + .WithMany("Wheels") + .HasForeignKey("CarId"); + + b.Navigation("Car"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Navigation("Wheels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/20251030141720_InitialCreate.Designer.cs b/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/20251030141720_InitialCreate.Designer.cs new file mode 100644 index 000000000..ed1b09ec5 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/20251030141720_InitialCreate.Designer.cs @@ -0,0 +1,222 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moryx.TestTools.Test.Model; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.Sqlite +{ + [DbContext(typeof(SqliteTestModelContext))] + [Migration("20251030141720_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("public") + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("TEXT"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("TEXT"); + + b.Property("Image") + .HasColumnType("BLOB"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDateLocal") + .HasColumnType("TEXT"); + + b.Property("ReleaseDateUtc") + .HasColumnType("TEXT"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Cars", "public"); + + b.HasDiscriminator("Discriminator").HasValue("CarEntity"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HouseEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("TEXT"); + + b.Property("IsBurnedDown") + .HasColumnType("INTEGER"); + + b.Property("IsMethLabratory") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Size") + .HasColumnType("INTEGER"); + + b.Property("ToRent") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Houses", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HugePocoEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Float1") + .HasColumnType("REAL"); + + b.Property("Float2") + .HasColumnType("REAL"); + + b.Property("Float3") + .HasColumnType("REAL"); + + b.Property("Float4") + .HasColumnType("REAL"); + + b.Property("Float5") + .HasColumnType("REAL"); + + b.Property("Name1") + .HasColumnType("TEXT"); + + b.Property("Name2") + .HasColumnType("TEXT"); + + b.Property("Name3") + .HasColumnType("TEXT"); + + b.Property("Name4") + .HasColumnType("TEXT"); + + b.Property("Name5") + .HasColumnType("TEXT"); + + b.Property("Number1") + .HasColumnType("INTEGER"); + + b.Property("Number2") + .HasColumnType("INTEGER"); + + b.Property("Number3") + .HasColumnType("INTEGER"); + + b.Property("Number4") + .HasColumnType("INTEGER"); + + b.Property("Number5") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("HugePocos", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.JsonEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JsonData") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Jsons", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CarId") + .HasColumnType("INTEGER"); + + b.Property("WheelType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CarId"); + + b.ToTable("Wheels", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.SportCarEntity", b => + { + b.HasBaseType("Moryx.TestTools.Test.Model.CarEntity"); + + b.Property("Performance") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("SportCarEntity"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.HasOne("Moryx.TestTools.Test.Model.CarEntity", "Car") + .WithMany("Wheels") + .HasForeignKey("CarId"); + + b.Navigation("Car"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Navigation("Wheels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/20251030141720_InitialCreate.cs b/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/20251030141720_InitialCreate.cs new file mode 100644 index 000000000..ef7cc90a8 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/20251030141720_InitialCreate.cs @@ -0,0 +1,155 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.Sqlite +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.EnsureSchema( + name: "public"); + + migrationBuilder.CreateTable( + name: "Cars", + schema: "public", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: true), + Price = table.Column(type: "INTEGER", nullable: false), + Image = table.Column(type: "BLOB", nullable: true), + ReleaseDateLocal = table.Column(type: "TEXT", nullable: false), + ReleaseDateUtc = table.Column(type: "TEXT", nullable: false), + Discriminator = table.Column(type: "TEXT", maxLength: 21, nullable: false), + Performance = table.Column(type: "INTEGER", nullable: true), + Created = table.Column(type: "TEXT", nullable: false), + Updated = table.Column(type: "TEXT", nullable: false), + Deleted = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Cars", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Houses", + schema: "public", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: true), + Size = table.Column(type: "INTEGER", nullable: false), + IsMethLabratory = table.Column(type: "INTEGER", nullable: false), + IsBurnedDown = table.Column(type: "INTEGER", nullable: false), + ToRent = table.Column(type: "INTEGER", nullable: false), + Created = table.Column(type: "TEXT", nullable: false), + Updated = table.Column(type: "TEXT", nullable: false), + Deleted = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Houses", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "HugePocos", + schema: "public", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Float1 = table.Column(type: "REAL", nullable: false), + Name1 = table.Column(type: "TEXT", nullable: true), + Number1 = table.Column(type: "INTEGER", nullable: false), + Float2 = table.Column(type: "REAL", nullable: false), + Name2 = table.Column(type: "TEXT", nullable: true), + Number2 = table.Column(type: "INTEGER", nullable: false), + Float3 = table.Column(type: "REAL", nullable: false), + Name3 = table.Column(type: "TEXT", nullable: true), + Number3 = table.Column(type: "INTEGER", nullable: false), + Float4 = table.Column(type: "REAL", nullable: false), + Name4 = table.Column(type: "TEXT", nullable: true), + Number4 = table.Column(type: "INTEGER", nullable: false), + Float5 = table.Column(type: "REAL", nullable: false), + Name5 = table.Column(type: "TEXT", nullable: true), + Number5 = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_HugePocos", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Jsons", + schema: "public", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + JsonData = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Jsons", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Wheels", + schema: "public", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CarId = table.Column(type: "INTEGER", nullable: true), + WheelType = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Wheels", x => x.Id); + table.ForeignKey( + name: "FK_Wheels_Cars_CarId", + column: x => x.CarId, + principalSchema: "public", + principalTable: "Cars", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Wheels_CarId", + schema: "public", + table: "Wheels", + column: "CarId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Houses", + schema: "public"); + + migrationBuilder.DropTable( + name: "HugePocos", + schema: "public"); + + migrationBuilder.DropTable( + name: "Jsons", + schema: "public"); + + migrationBuilder.DropTable( + name: "Wheels", + schema: "public"); + + migrationBuilder.DropTable( + name: "Cars", + schema: "public"); + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/SqliteTestModelContextModelSnapshot.cs b/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/SqliteTestModelContextModelSnapshot.cs new file mode 100644 index 000000000..746f3a61f --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/Migrations/Sqlite/SqliteTestModelContextModelSnapshot.cs @@ -0,0 +1,219 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moryx.TestTools.Test.Model; + +#nullable disable + +namespace Moryx.TestTools.Test.Model.Migrations.Sqlite +{ + [DbContext(typeof(SqliteTestModelContext))] + partial class SqliteTestModelContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasDefaultSchema("public") + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("TEXT"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("TEXT"); + + b.Property("Image") + .HasColumnType("BLOB"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDateLocal") + .HasColumnType("TEXT"); + + b.Property("ReleaseDateUtc") + .HasColumnType("TEXT"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Cars", "public"); + + b.HasDiscriminator("Discriminator").HasValue("CarEntity"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HouseEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("TEXT"); + + b.Property("IsBurnedDown") + .HasColumnType("INTEGER"); + + b.Property("IsMethLabratory") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Size") + .HasColumnType("INTEGER"); + + b.Property("ToRent") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Houses", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.HugePocoEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Float1") + .HasColumnType("REAL"); + + b.Property("Float2") + .HasColumnType("REAL"); + + b.Property("Float3") + .HasColumnType("REAL"); + + b.Property("Float4") + .HasColumnType("REAL"); + + b.Property("Float5") + .HasColumnType("REAL"); + + b.Property("Name1") + .HasColumnType("TEXT"); + + b.Property("Name2") + .HasColumnType("TEXT"); + + b.Property("Name3") + .HasColumnType("TEXT"); + + b.Property("Name4") + .HasColumnType("TEXT"); + + b.Property("Name5") + .HasColumnType("TEXT"); + + b.Property("Number1") + .HasColumnType("INTEGER"); + + b.Property("Number2") + .HasColumnType("INTEGER"); + + b.Property("Number3") + .HasColumnType("INTEGER"); + + b.Property("Number4") + .HasColumnType("INTEGER"); + + b.Property("Number5") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("HugePocos", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.JsonEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JsonData") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Jsons", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CarId") + .HasColumnType("INTEGER"); + + b.Property("WheelType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CarId"); + + b.ToTable("Wheels", "public"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.SportCarEntity", b => + { + b.HasBaseType("Moryx.TestTools.Test.Model.CarEntity"); + + b.Property("Performance") + .HasColumnType("INTEGER"); + + b.HasDiscriminator().HasValue("SportCarEntity"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.WheelEntity", b => + { + b.HasOne("Moryx.TestTools.Test.Model.CarEntity", "Car") + .WithMany("Wheels") + .HasForeignKey("CarId"); + + b.Navigation("Car"); + }); + + modelBuilder.Entity("Moryx.TestTools.Test.Model.CarEntity", b => + { + b.Navigation("Wheels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj index 2051f30f4..78076bfb1 100644 --- a/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj +++ b/src/Moryx.TestTools.Test.Model/Moryx.TestTools.Test.Model.csproj @@ -11,6 +11,8 @@ + + diff --git a/src/Moryx.TestTools.Test.Model/NpgsqlTestModelContext.cs b/src/Moryx.TestTools.Test.Model/NpgsqlTestModelContext.cs new file mode 100644 index 000000000..45e41ac44 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/NpgsqlTestModelContext.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Moryx.Model.Attributes; +using System.IO; +using Moryx.Model.PostgreSQL; +using Moryx.Model.PostgreSQL.Attributes; + +namespace Moryx.TestTools.Test.Model; + +[NpgsqlDatabaseContext] +[ModelConfigurator(typeof(NpgsqlModelConfigurator))] +public class NpgsqlTestModelContext : TestModelContext +{ + public NpgsqlTestModelContext() + { + } + + public NpgsqlTestModelContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + + if (!optionsBuilder.IsConfigured) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + var connectionString = configuration.GetConnectionString("Moryx.TestTools.Test.Model"); + optionsBuilder.UseNpgsql(connectionString); + } + + optionsBuilder.UseLazyLoadingProxies(); + } +} \ No newline at end of file diff --git a/src/Moryx.TestTools.Test.Model/README.md b/src/Moryx.TestTools.Test.Model/README.md index dc63f72ab..a2a153b91 100644 --- a/src/Moryx.TestTools.Test.Model/README.md +++ b/src/Moryx.TestTools.Test.Model/README.md @@ -1,3 +1,5 @@ -dotnet ef migrations add InitialCreate --startup-project ..\StartProject.Core\StartProject.Core.csproj -dotnet ef database update InitialCreate --startup-project ..\StartProject.Core\StartProject.Core.csproj +dotnet ef migrations add InitialCreate -s ../StartProject.Asp/StartProject.Asp.csproj -o ./Migrations/SqlServer -c SqlServerTestModelContext +dotnet ef migrations add InitialCreate -s ../StartProject.Asp/StartProject.Asp.csproj -o ./Migrations/Sqlite -c SqliteTestModelContext +dotnet ef migrations add InitialCreate -s ../StartProject.Asp/StartProject.Asp.csproj -o ./Migrations/Npgsql -c NpgsqlTestModelContext +dotnet ef database update InitialCreate --startup-project ..\StartProject.Core\StartProject.Core.csproj diff --git a/src/Moryx.TestTools.Test.Model/SqlServerTestModelContext.cs b/src/Moryx.TestTools.Test.Model/SqlServerTestModelContext.cs new file mode 100644 index 000000000..e8884adfa --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/SqlServerTestModelContext.cs @@ -0,0 +1,47 @@ +// Copyright (c) 2025, Phoenix Contact GmbH & Co. KG +// Licensed under the Apache License, Version 2.0 + +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Moryx.Model.Attributes; +using Moryx.Model.SqlServer; +using Moryx.TestTools.Test.Model; +using System.IO; + +// ReSharper disable once CheckNamespace +namespace Moryx.Resources.Model; + +/// +/// SqlServer specific implementation of +/// +[SqlServerDatabaseContext] +[ModelConfigurator(typeof(SqlServerModelConfigurator))] +[DefaultSchema("resources")] +public class SqlServerTestModelContext : TestModelContext +{ + /// + public SqlServerTestModelContext() + { + } + + /// + public SqlServerTestModelContext(DbContextOptions options) : base(options) + { + } + + /// + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + + if (!optionsBuilder.IsConfigured) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + var connectionString = configuration.GetConnectionString("Moryx.Resources.Model"); + optionsBuilder.UseSqlServer(connectionString); + } + } +} \ No newline at end of file diff --git a/src/Moryx.TestTools.Test.Model/SqliteTestModelContext.cs b/src/Moryx.TestTools.Test.Model/SqliteTestModelContext.cs new file mode 100644 index 000000000..20751f3e4 --- /dev/null +++ b/src/Moryx.TestTools.Test.Model/SqliteTestModelContext.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Moryx.Model.Attributes; +using System.IO; +using Moryx.Model.Sqlite; +using Moryx.Model.Sqlite.Attributes; + +namespace Moryx.TestTools.Test.Model; + +[SqliteContext] +[ModelConfigurator(typeof(SqliteModelConfigurator))] +public class SqliteTestModelContext : TestModelContext +{ + public SqliteTestModelContext() + { + } + + public SqliteTestModelContext(DbContextOptions options) : base(options) + { + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + base.OnConfiguring(optionsBuilder); + + if (!optionsBuilder.IsConfigured) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + var connectionString = configuration.GetConnectionString("Moryx.TestTools.Test.Model"); + optionsBuilder.UseSqlite(connectionString); + } + + optionsBuilder.UseLazyLoadingProxies(); + } +} \ No newline at end of file diff --git a/src/Moryx.TestTools.Test.Model/TestModelContext.cs b/src/Moryx.TestTools.Test.Model/TestModelContext.cs index 0fef9b96d..502e96f9c 100644 --- a/src/Moryx.TestTools.Test.Model/TestModelContext.cs +++ b/src/Moryx.TestTools.Test.Model/TestModelContext.cs @@ -1,9 +1,7 @@ // Copyright (c) 2023, Phoenix Contact GmbH & Co. KG // Licensed under the Apache License, Version 2.0 -using System.IO; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using Moryx.Model; namespace Moryx.TestTools.Test.Model @@ -20,23 +18,7 @@ public TestModelContext() public TestModelContext(DbContextOptions options) : base(options) { } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - base.OnConfiguring(optionsBuilder); - - if (!optionsBuilder.IsConfigured) - { - var configuration = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json") - .Build(); - var connectionString = configuration.GetConnectionString("Moryx.TestTools.Test.Model"); - optionsBuilder.UseNpgsql(connectionString); - } - - optionsBuilder.UseLazyLoadingProxies(); - } + public virtual DbSet Cars { get; set; } public virtual DbSet Wheels { get; set; } diff --git a/src/StartProject.Asp/StartProject.Asp.csproj b/src/StartProject.Asp/StartProject.Asp.csproj index 9fd92e5b9..1a985ea15 100644 --- a/src/StartProject.Asp/StartProject.Asp.csproj +++ b/src/StartProject.Asp/StartProject.Asp.csproj @@ -27,4 +27,8 @@ + + + +