From ea9d0329365a93331ab738280745b86789c2f6de Mon Sep 17 00:00:00 2001 From: DavidMakarov Date: Thu, 25 Apr 2024 20:09:08 +0400 Subject: [PATCH] full hard_lab3 --- FlowerShop/FlowerShop/FlowerShopView.csproj | 2 +- .../FlowerShop/FormComponent.Designer.cs | 33 ++-- .../FormFlowerComponent.Designer.cs | 33 ++-- FlowerShop/FlowerShop/FormMain.cs | 1 - .../FlowerShopBusinessLogic.csproj | 2 +- .../FlowerShopContracts.csproj | 2 +- .../FlowerShopDataModels.csproj | 2 +- .../FlowerShopDatabase.cs | 6 +- .../FlowerShopDatabaseImplement.csproj | 3 +- .../Implements/ShopStorage.cs | 146 ++++++++++++++ .../20240308215929_InitialCreate.cs | 122 ------------ ... => 20240425154411_InitCreate.Designer.cs} | 130 ++++++++++--- .../Migrations/20240425154411_InitCreate.cs | 182 ++++++++++++++++++ .../FlowerShopDatabaseModelSnapshot.cs | 126 +++++++++--- .../Models/Shop.cs | 104 ++++++++++ .../Models/ShopFlower.cs | 17 ++ .../FlowerShopFileImplement.csproj | 2 +- .../FlowerShopListImplement.csproj | 2 +- 18 files changed, 704 insertions(+), 211 deletions(-) create mode 100644 FlowerShop/FlowerShopDatabaseImplement/Implements/ShopStorage.cs delete mode 100644 FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.cs rename FlowerShop/FlowerShopDatabaseImplement/Migrations/{20240308215929_InitialCreate.Designer.cs => 20240425154411_InitCreate.Designer.cs} (50%) create mode 100644 FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.cs create mode 100644 FlowerShop/FlowerShopDatabaseImplement/Models/Shop.cs create mode 100644 FlowerShop/FlowerShopDatabaseImplement/Models/ShopFlower.cs diff --git a/FlowerShop/FlowerShop/FlowerShopView.csproj b/FlowerShop/FlowerShop/FlowerShopView.csproj index 83f9c52..c843b3a 100644 --- a/FlowerShop/FlowerShop/FlowerShopView.csproj +++ b/FlowerShop/FlowerShop/FlowerShopView.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows + net7.0-windows7.0 enable true enable diff --git a/FlowerShop/FlowerShop/FormComponent.Designer.cs b/FlowerShop/FlowerShop/FormComponent.Designer.cs index b9bcc58..9fbbdb3 100644 --- a/FlowerShop/FlowerShop/FormComponent.Designer.cs +++ b/FlowerShop/FlowerShop/FormComponent.Designer.cs @@ -39,40 +39,43 @@ // label1 // label1.AutoSize = true; - label1.Location = new Point(27, 15); + label1.Location = new Point(31, 20); label1.Name = "label1"; - label1.Size = new Size(62, 15); + label1.Size = new Size(80, 20); label1.TabIndex = 3; label1.Text = "Название:"; // // textBoxName // - textBoxName.Location = new Point(92, 12); + textBoxName.Location = new Point(123, 17); + textBoxName.Margin = new Padding(3, 4, 3, 4); textBoxName.Name = "textBoxName"; - textBoxName.Size = new Size(213, 23); + textBoxName.Size = new Size(243, 27); textBoxName.TabIndex = 2; // // label2 // label2.AutoSize = true; - label2.Location = new Point(27, 44); + label2.Location = new Point(31, 59); label2.Name = "label2"; - label2.Size = new Size(38, 15); + label2.Size = new Size(48, 20); label2.TabIndex = 5; label2.Text = "Цена:"; // // textBoxCost // - textBoxCost.Location = new Point(92, 41); + textBoxCost.Location = new Point(123, 56); + textBoxCost.Margin = new Padding(3, 4, 3, 4); textBoxCost.Name = "textBoxCost"; - textBoxCost.Size = new Size(152, 23); + textBoxCost.Size = new Size(173, 27); textBoxCost.TabIndex = 4; // // buttonSave // - buttonSave.Location = new Point(169, 93); + buttonSave.Location = new Point(230, 124); + buttonSave.Margin = new Padding(3, 4, 3, 4); buttonSave.Name = "buttonSave"; - buttonSave.Size = new Size(75, 23); + buttonSave.Size = new Size(94, 31); buttonSave.TabIndex = 6; buttonSave.Text = "Сохранить"; buttonSave.UseVisualStyleBackColor = true; @@ -80,9 +83,10 @@ // // buttonCancel // - buttonCancel.Location = new Point(250, 93); + buttonCancel.Location = new Point(330, 124); + buttonCancel.Margin = new Padding(3, 4, 3, 4); buttonCancel.Name = "buttonCancel"; - buttonCancel.Size = new Size(75, 23); + buttonCancel.Size = new Size(86, 31); buttonCancel.TabIndex = 7; buttonCancel.Text = "Отмена"; buttonCancel.UseVisualStyleBackColor = true; @@ -90,15 +94,16 @@ // // FormComponent // - AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(342, 134); + ClientSize = new Size(428, 179); Controls.Add(buttonCancel); Controls.Add(buttonSave); Controls.Add(label2); Controls.Add(textBoxCost); Controls.Add(label1); Controls.Add(textBoxName); + Margin = new Padding(3, 4, 3, 4); Name = "FormComponent"; Text = "Компонент"; Load += FormComponent_Load; diff --git a/FlowerShop/FlowerShop/FormFlowerComponent.Designer.cs b/FlowerShop/FlowerShop/FormFlowerComponent.Designer.cs index c6d43a0..aff6c1e 100644 --- a/FlowerShop/FlowerShop/FormFlowerComponent.Designer.cs +++ b/FlowerShop/FlowerShop/FormFlowerComponent.Designer.cs @@ -40,41 +40,44 @@ // comboBoxComponent.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxComponent.FormattingEnabled = true; - comboBoxComponent.Location = new Point(88, 9); + comboBoxComponent.Location = new Point(126, 13); + comboBoxComponent.Margin = new Padding(3, 4, 3, 4); comboBoxComponent.Name = "comboBoxComponent"; - comboBoxComponent.Size = new Size(250, 23); + comboBoxComponent.Size = new Size(285, 28); comboBoxComponent.TabIndex = 0; // // textBoxCount // - textBoxCount.Location = new Point(88, 38); + textBoxCount.Location = new Point(126, 52); + textBoxCount.Margin = new Padding(3, 4, 3, 4); textBoxCount.Name = "textBoxCount"; - textBoxCount.Size = new Size(250, 23); + textBoxCount.Size = new Size(285, 27); textBoxCount.TabIndex = 1; // // label1 // label1.AutoSize = true; - label1.Location = new Point(10, 12); + label1.Location = new Point(11, 16); label1.Name = "label1"; - label1.Size = new Size(72, 15); + label1.Size = new Size(91, 20); label1.TabIndex = 2; label1.Text = "Компонент:"; // // label2 // label2.AutoSize = true; - label2.Location = new Point(10, 41); + label2.Location = new Point(11, 55); label2.Name = "label2"; - label2.Size = new Size(75, 15); + label2.Size = new Size(93, 20); label2.TabIndex = 3; label2.Text = "Количество:"; // // buttonAdd // - buttonAdd.Location = new Point(154, 80); + buttonAdd.Location = new Point(203, 109); + buttonAdd.Margin = new Padding(3, 4, 3, 4); buttonAdd.Name = "buttonAdd"; - buttonAdd.Size = new Size(86, 23); + buttonAdd.Size = new Size(98, 31); buttonAdd.TabIndex = 4; buttonAdd.Text = "Сохранить"; buttonAdd.UseVisualStyleBackColor = true; @@ -82,9 +85,10 @@ // // buttonCancel // - buttonCancel.Location = new Point(246, 80); + buttonCancel.Location = new Point(308, 109); + buttonCancel.Margin = new Padding(3, 4, 3, 4); buttonCancel.Name = "buttonCancel"; - buttonCancel.Size = new Size(86, 23); + buttonCancel.Size = new Size(98, 31); buttonCancel.TabIndex = 5; buttonCancel.Text = "Отмена"; buttonCancel.UseVisualStyleBackColor = true; @@ -92,15 +96,16 @@ // // FormFlowerComponent // - AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(350, 115); + ClientSize = new Size(423, 153); Controls.Add(buttonCancel); Controls.Add(buttonAdd); Controls.Add(label2); Controls.Add(label1); Controls.Add(textBoxCount); Controls.Add(comboBoxComponent); + Margin = new Padding(3, 4, 3, 4); Name = "FormFlowerComponent"; Text = "Компоненты цветов"; ResumeLayout(false); diff --git a/FlowerShop/FlowerShop/FormMain.cs b/FlowerShop/FlowerShop/FormMain.cs index bde1d6e..9e57bee 100644 --- a/FlowerShop/FlowerShop/FormMain.cs +++ b/FlowerShop/FlowerShop/FormMain.cs @@ -28,7 +28,6 @@ namespace FlowerShopView { dataGridView.DataSource = list; dataGridView.Columns["FlowerId"].Visible = false; - dataGridView.Columns["FlowerName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } } catch (Exception ex) diff --git a/FlowerShop/FlowerShopBusinessLogic/FlowerShopBusinessLogic.csproj b/FlowerShop/FlowerShopBusinessLogic/FlowerShopBusinessLogic.csproj index 00938d3..e1222b5 100644 --- a/FlowerShop/FlowerShopBusinessLogic/FlowerShopBusinessLogic.csproj +++ b/FlowerShop/FlowerShopBusinessLogic/FlowerShopBusinessLogic.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj b/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj index 5192185..5b8e324 100644 --- a/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj +++ b/FlowerShop/FlowerShopContracts/FlowerShopContracts.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/FlowerShop/FlowerShopDataModels/FlowerShopDataModels.csproj b/FlowerShop/FlowerShopDataModels/FlowerShopDataModels.csproj index 132c02c..cfadb03 100644 --- a/FlowerShop/FlowerShopDataModels/FlowerShopDataModels.csproj +++ b/FlowerShop/FlowerShopDataModels/FlowerShopDataModels.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabase.cs b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabase.cs index c92b773..ff1ddea 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabase.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabase.cs @@ -9,13 +9,17 @@ namespace FlowerShopDatabaseImplement { if (optionsBuilder.IsConfigured == false) { - optionsBuilder.UseSqlServer(@"Data Source=WHITEBEAR\SQLEXPRESS;Initial Catalog=FlowerShopDatabaseFull;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + optionsBuilder.UseNpgsql(@"Host=localhost;Database=FlowerShopHardDatabaseFull;Username=postgres;Password=postgres"); } base.OnConfiguring(optionsBuilder); + AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); + AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true); } public virtual DbSet Components { set; get; } public virtual DbSet Flowers { set; get; } public virtual DbSet FlowerComponents { set; get; } public virtual DbSet Orders { set; get; } + public virtual DbSet Shops { set; get; } + public virtual DbSet ShopFlowers { set; get; } } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj index 7ecbc47..436990e 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj +++ b/FlowerShop/FlowerShopDatabaseImplement/FlowerShopDatabaseImplement.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable @@ -13,6 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/FlowerShop/FlowerShopDatabaseImplement/Implements/ShopStorage.cs b/FlowerShop/FlowerShopDatabaseImplement/Implements/ShopStorage.cs new file mode 100644 index 0000000..1ec6dca --- /dev/null +++ b/FlowerShop/FlowerShopDatabaseImplement/Implements/ShopStorage.cs @@ -0,0 +1,146 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.SearchModels; +using FlowerShopContracts.StoragesContracts; +using FlowerShopContracts.ViewModels; +using FlowerShopDatabaseImplement.Models; +using FlowerShopDataModels.Models; +using Microsoft.EntityFrameworkCore; + +namespace FlowerShopDatabaseImplement.Implements +{ + public class ShopStorage : IShopStorage + { + public List GetFullList() + { + using var context = new FlowerShopDatabase(); + return context.Shops + .Include(x => x.Flowers) + .ThenInclude(x => x.Flower) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFilteredList(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName)) + { + return new(); + } + using var context = new FlowerShopDatabase(); + return context.Shops + .Include(x => x.Flowers) + .ThenInclude(x => x.Flower) + .Where(x => x.ShopName.Contains(model.ShopName)) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public ShopViewModel? GetElement(ShopSearchModel model) + { + if (string.IsNullOrEmpty(model.ShopName) && !model.Id.HasValue) + { + return null; + } + using var context = new FlowerShopDatabase(); + return context.Shops + .Include(x => x.Flowers) + .ThenInclude(x => x.Flower) + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.ShopName) && x.ShopName == model.ShopName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + + public ShopViewModel? Insert(ShopBindingModel model) + { + using var context = new FlowerShopDatabase(); + var newShop = Shop.Create(context, model); + if (newShop == null) + { + return null; + } + context.Shops.Add(newShop); + context.SaveChanges(); + return newShop.GetViewModel; + } + + public ShopViewModel? Update(ShopBindingModel model) + { + using var context = new FlowerShopDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var shop = context.Shops.FirstOrDefault(rec => rec.Id == model.Id); + if (shop == null) + { + return null; + } + shop.Update(model); + context.SaveChanges(); + shop.UpdateFlowers(context, model); + transaction.Commit(); + return shop.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + public ShopViewModel? Delete(ShopBindingModel model) + { + using var context = new FlowerShopDatabase(); + var element = context.Shops + .Include(x => x.Flowers) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Shops.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public bool MakeSale(IFlowerModel model, int count) + { + using var context = new FlowerShopDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + foreach (var shop in context.Shops.Include(x => x.Flowers).ThenInclude(x => x.Flower) + .Where(x => x.Flowers.Any(x => x.FlowerId == model.Id)) + .ToList()) + { + var flower = shop.ShopFlowers[model.Id]; + int min = Math.Min(flower.Item2, count); + if (min == flower.Item2) + { + shop.ShopFlowers.Remove(model.Id); + } + else + { + shop.ShopFlowers[model.Id] = (flower.Item1, flower.Item2 - min); + } + shop.UpdateFlowers(context, new() { Id = shop.Id, ShopFlowers = shop.ShopFlowers }); + count -= min; + if (count == 0) + { + context.SaveChanges(); + transaction.Commit(); + return true; + } + } + transaction.Rollback(); + return false; + } + catch + { + transaction.Rollback(); + throw; + } + } + } +} diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.cs deleted file mode 100644 index 5559573..0000000 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace FlowerShopDatabaseImplement.Migrations -{ - public partial class InitialCreate : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Components", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - ComponentName = table.Column(type: "nvarchar(max)", nullable: false), - Cost = table.Column(type: "float", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Components", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Flowers", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - FlowerName = table.Column(type: "nvarchar(max)", nullable: false), - Price = table.Column(type: "float", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Flowers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "FlowerComponents", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - FlowerId = table.Column(type: "int", nullable: false), - ComponentId = table.Column(type: "int", nullable: false), - Count = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_FlowerComponents", x => x.Id); - table.ForeignKey( - name: "FK_FlowerComponents_Components_ComponentId", - column: x => x.ComponentId, - principalTable: "Components", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_FlowerComponents_Flowers_FlowerId", - column: x => x.FlowerId, - principalTable: "Flowers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Orders", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - FlowerId = table.Column(type: "int", nullable: false), - Count = table.Column(type: "int", nullable: false), - Sum = table.Column(type: "float", nullable: false), - Status = table.Column(type: "int", nullable: false), - DateCreate = table.Column(type: "datetime2", nullable: false), - DateImplement = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Orders", x => x.Id); - table.ForeignKey( - name: "FK_Orders_Flowers_FlowerId", - column: x => x.FlowerId, - principalTable: "Flowers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_FlowerComponents_ComponentId", - table: "FlowerComponents", - column: "ComponentId"); - - migrationBuilder.CreateIndex( - name: "IX_FlowerComponents_FlowerId", - table: "FlowerComponents", - column: "FlowerId"); - - migrationBuilder.CreateIndex( - name: "IX_Orders_FlowerId", - table: "Orders", - column: "FlowerId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "FlowerComponents"); - - migrationBuilder.DropTable( - name: "Orders"); - - migrationBuilder.DropTable( - name: "Components"); - - migrationBuilder.DropTable( - name: "Flowers"); - } - } -} diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.Designer.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.Designer.cs similarity index 50% rename from FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.Designer.cs rename to FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.Designer.cs index 72f544b..5a56d43 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240308215929_InitialCreate.Designer.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.Designer.cs @@ -3,41 +3,41 @@ using System; using FlowerShopDatabaseImplement; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #nullable disable namespace FlowerShopDatabaseImplement.Migrations { [DbContext(typeof(FlowerShopDatabase))] - [Migration("20240308215929_InitialCreate")] - partial class InitialCreate + [Migration("20240425154411_InitCreate")] + partial class InitCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "6.0.27") - .HasAnnotation("Relational:MaxIdentifierLength", 128); + .HasAnnotation("Relational:MaxIdentifierLength", 63); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("ComponentName") .IsRequired() - .HasColumnType("nvarchar(max)"); + .HasColumnType("text"); b.Property("Cost") - .HasColumnType("float"); + .HasColumnType("double precision"); b.HasKey("Id"); @@ -48,16 +48,16 @@ namespace FlowerShopDatabaseImplement.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("FlowerName") .IsRequired() - .HasColumnType("nvarchar(max)"); + .HasColumnType("text"); b.Property("Price") - .HasColumnType("float"); + .HasColumnType("double precision"); b.HasKey("Id"); @@ -68,18 +68,18 @@ namespace FlowerShopDatabaseImplement.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("ComponentId") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("Count") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("FlowerId") - .HasColumnType("int"); + .HasColumnType("integer"); b.HasKey("Id"); @@ -94,28 +94,27 @@ namespace FlowerShopDatabaseImplement.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Count") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("DateCreate") - .HasColumnType("datetime2"); + .HasColumnType("timestamp without time zone"); b.Property("DateImplement") - .IsRequired() - .HasColumnType("datetime2"); + .HasColumnType("timestamp without time zone"); b.Property("FlowerId") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("Status") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("Sum") - .HasColumnType("float"); + .HasColumnType("double precision"); b.HasKey("Id"); @@ -124,6 +123,59 @@ namespace FlowerShopDatabaseImplement.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("text"); + + b.Property("DateOpening") + .HasColumnType("timestamp without time zone"); + + b.Property("MaximumFlowers") + .HasColumnType("integer"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.ShopFlower", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("FlowerId") + .HasColumnType("integer"); + + b.Property("ShopId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FlowerId"); + + b.HasIndex("ShopId"); + + b.ToTable("ShopFlowers"); + }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.FlowerComponent", b => { b.HasOne("FlowerShopDatabaseImplement.Models.Component", "Component") @@ -152,6 +204,25 @@ namespace FlowerShopDatabaseImplement.Migrations .IsRequired(); }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.ShopFlower", b => + { + b.HasOne("FlowerShopDatabaseImplement.Models.Flower", "Flower") + .WithMany() + .HasForeignKey("FlowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FlowerShopDatabaseImplement.Models.Shop", "Shop") + .WithMany("Flowers") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Flower"); + + b.Navigation("Shop"); + }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => { b.Navigation("FlowerComponents"); @@ -163,6 +234,11 @@ namespace FlowerShopDatabaseImplement.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Shop", b => + { + b.Navigation("Flowers"); + }); #pragma warning restore 612, 618 } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.cs new file mode 100644 index 0000000..575ed8f --- /dev/null +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/20240425154411_InitCreate.cs @@ -0,0 +1,182 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace FlowerShopDatabaseImplement.Migrations +{ + public partial class InitCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Components", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ComponentName = table.Column(type: "text", nullable: false), + Cost = table.Column(type: "double precision", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Components", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Flowers", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + FlowerName = table.Column(type: "text", nullable: false), + Price = table.Column(type: "double precision", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Flowers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Shops", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ShopName = table.Column(type: "text", nullable: false), + Address = table.Column(type: "text", nullable: false), + DateOpening = table.Column(type: "timestamp without time zone", nullable: false), + MaximumFlowers = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Shops", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "FlowerComponents", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + FlowerId = table.Column(type: "integer", nullable: false), + ComponentId = table.Column(type: "integer", nullable: false), + Count = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FlowerComponents", x => x.Id); + table.ForeignKey( + name: "FK_FlowerComponents_Components_ComponentId", + column: x => x.ComponentId, + principalTable: "Components", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_FlowerComponents_Flowers_FlowerId", + column: x => x.FlowerId, + principalTable: "Flowers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + FlowerId = table.Column(type: "integer", nullable: false), + Count = table.Column(type: "integer", nullable: false), + Sum = table.Column(type: "double precision", nullable: false), + Status = table.Column(type: "integer", nullable: false), + DateCreate = table.Column(type: "timestamp without time zone", nullable: false), + DateImplement = table.Column(type: "timestamp without time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + table.ForeignKey( + name: "FK_Orders_Flowers_FlowerId", + column: x => x.FlowerId, + principalTable: "Flowers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ShopFlowers", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ShopId = table.Column(type: "integer", nullable: false), + FlowerId = table.Column(type: "integer", nullable: false), + Count = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShopFlowers", x => x.Id); + table.ForeignKey( + name: "FK_ShopFlowers_Flowers_FlowerId", + column: x => x.FlowerId, + principalTable: "Flowers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ShopFlowers_Shops_ShopId", + column: x => x.ShopId, + principalTable: "Shops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_FlowerComponents_ComponentId", + table: "FlowerComponents", + column: "ComponentId"); + + migrationBuilder.CreateIndex( + name: "IX_FlowerComponents_FlowerId", + table: "FlowerComponents", + column: "FlowerId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_FlowerId", + table: "Orders", + column: "FlowerId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopFlowers_FlowerId", + table: "ShopFlowers", + column: "FlowerId"); + + migrationBuilder.CreateIndex( + name: "IX_ShopFlowers_ShopId", + table: "ShopFlowers", + column: "ShopId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "FlowerComponents"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "ShopFlowers"); + + migrationBuilder.DropTable( + name: "Components"); + + migrationBuilder.DropTable( + name: "Flowers"); + + migrationBuilder.DropTable( + name: "Shops"); + } + } +} diff --git a/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs b/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs index d93d19a..9c5a37a 100644 --- a/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs +++ b/FlowerShop/FlowerShopDatabaseImplement/Migrations/FlowerShopDatabaseModelSnapshot.cs @@ -3,8 +3,8 @@ using System; using FlowerShopDatabaseImplement; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #nullable disable @@ -18,24 +18,24 @@ namespace FlowerShopDatabaseImplement.Migrations #pragma warning disable 612, 618 modelBuilder .HasAnnotation("ProductVersion", "6.0.27") - .HasAnnotation("Relational:MaxIdentifierLength", 128); + .HasAnnotation("Relational:MaxIdentifierLength", 63); - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("ComponentName") .IsRequired() - .HasColumnType("nvarchar(max)"); + .HasColumnType("text"); b.Property("Cost") - .HasColumnType("float"); + .HasColumnType("double precision"); b.HasKey("Id"); @@ -46,16 +46,16 @@ namespace FlowerShopDatabaseImplement.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("FlowerName") .IsRequired() - .HasColumnType("nvarchar(max)"); + .HasColumnType("text"); b.Property("Price") - .HasColumnType("float"); + .HasColumnType("double precision"); b.HasKey("Id"); @@ -66,18 +66,18 @@ namespace FlowerShopDatabaseImplement.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("ComponentId") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("Count") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("FlowerId") - .HasColumnType("int"); + .HasColumnType("integer"); b.HasKey("Id"); @@ -92,28 +92,27 @@ namespace FlowerShopDatabaseImplement.Migrations { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("integer"); - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1); + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("Count") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("DateCreate") - .HasColumnType("datetime2"); + .HasColumnType("timestamp without time zone"); b.Property("DateImplement") - .IsRequired() - .HasColumnType("datetime2"); + .HasColumnType("timestamp without time zone"); b.Property("FlowerId") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("Status") - .HasColumnType("int"); + .HasColumnType("integer"); b.Property("Sum") - .HasColumnType("float"); + .HasColumnType("double precision"); b.HasKey("Id"); @@ -122,6 +121,59 @@ namespace FlowerShopDatabaseImplement.Migrations b.ToTable("Orders"); }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Shop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("text"); + + b.Property("DateOpening") + .HasColumnType("timestamp without time zone"); + + b.Property("MaximumFlowers") + .HasColumnType("integer"); + + b.Property("ShopName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Shops"); + }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.ShopFlower", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("FlowerId") + .HasColumnType("integer"); + + b.Property("ShopId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FlowerId"); + + b.HasIndex("ShopId"); + + b.ToTable("ShopFlowers"); + }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.FlowerComponent", b => { b.HasOne("FlowerShopDatabaseImplement.Models.Component", "Component") @@ -150,6 +202,25 @@ namespace FlowerShopDatabaseImplement.Migrations .IsRequired(); }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.ShopFlower", b => + { + b.HasOne("FlowerShopDatabaseImplement.Models.Flower", "Flower") + .WithMany() + .HasForeignKey("FlowerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("FlowerShopDatabaseImplement.Models.Shop", "Shop") + .WithMany("Flowers") + .HasForeignKey("ShopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Flower"); + + b.Navigation("Shop"); + }); + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Component", b => { b.Navigation("FlowerComponents"); @@ -161,6 +232,11 @@ namespace FlowerShopDatabaseImplement.Migrations b.Navigation("Orders"); }); + + modelBuilder.Entity("FlowerShopDatabaseImplement.Models.Shop", b => + { + b.Navigation("Flowers"); + }); #pragma warning restore 612, 618 } } diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/Shop.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/Shop.cs new file mode 100644 index 0000000..5e82527 --- /dev/null +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/Shop.cs @@ -0,0 +1,104 @@ +using FlowerShopContracts.BindingModels; +using FlowerShopContracts.ViewModels; +using FlowerShopDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace FlowerShopDatabaseImplement.Models +{ + public class Shop : IShopModel + { + public int Id { get; set; } + [Required] + public string ShopName { get; set; } = string.Empty; + [Required] + public string Address { get; set; } = string.Empty; + [Required] + public DateTime DateOpening { get; set; } + [Required] + public int MaximumFlowers { get; set; } + private Dictionary? _shopFlowers = null; + [NotMapped] + public Dictionary ShopFlowers + { + get + { + if (_shopFlowers == null) + { + _shopFlowers = Flowers + .ToDictionary(x => x.FlowerId, x => (x.Flower as IFlowerModel, x.Count)); + } + return _shopFlowers; + } + } + + [ForeignKey("ShopId")] + public virtual List Flowers { get; set; } = new(); + + public static Shop Create(FlowerShopDatabase context, ShopBindingModel model) + { + return new Shop() + { + Id = model.Id, + ShopName = model.ShopName, + Address = model.Address, + DateOpening = model.DateOpening, + MaximumFlowers = model.MaximumFlowers, + Flowers = model.ShopFlowers.Select(x => new ShopFlower + { + Flower = context.Flowers.First(y => y.Id == x.Key), + Count = x.Value.Item2 + }).ToList() + }; + } + + public void Update(ShopBindingModel model) + { + ShopName = model.ShopName; + Address = model.Address; + DateOpening = model.DateOpening; + MaximumFlowers = model.MaximumFlowers; + } + + public ShopViewModel GetViewModel => new() + { + Id = Id, + ShopName = ShopName, + Address = Address, + DateOpening = DateOpening, + MaximumFlowers = MaximumFlowers, + ShopFlowers = ShopFlowers + }; + + public void UpdateFlowers(FlowerShopDatabase context, ShopBindingModel model) + { + var shopFlowers = context.ShopFlowers.Where(rec => rec.ShopId == model.Id).ToList(); + if (shopFlowers != null && shopFlowers.Count > 0) + { + context.ShopFlowers.RemoveRange(shopFlowers.Where(rec => !model.ShopFlowers.ContainsKey(rec.FlowerId))); + context.SaveChanges(); + foreach (var updateFlower in shopFlowers) + { + if (model.ShopFlowers.ContainsKey(updateFlower.FlowerId)) + { + updateFlower.Count = model.ShopFlowers[updateFlower.FlowerId].Item2; + model.ShopFlowers.Remove(updateFlower.FlowerId); + } + } + context.SaveChanges(); + } + var shop = context.Shops.First(x => x.Id == Id); + foreach (var ic in model.ShopFlowers) + { + context.ShopFlowers.Add(new ShopFlower + { + Shop = shop, + Flower = context.Flowers.First(x => x.Id == ic.Key), + Count = ic.Value.Item2 + }); + context.SaveChanges(); + } + _shopFlowers = null; + } + } +} diff --git a/FlowerShop/FlowerShopDatabaseImplement/Models/ShopFlower.cs b/FlowerShop/FlowerShopDatabaseImplement/Models/ShopFlower.cs new file mode 100644 index 0000000..b3ec476 --- /dev/null +++ b/FlowerShop/FlowerShopDatabaseImplement/Models/ShopFlower.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace FlowerShopDatabaseImplement.Models +{ + public class ShopFlower + { + public int Id { get; set; } + [Required] + public int ShopId { get; set; } + [Required] + public int FlowerId { get; set; } + [Required] + public int Count { get; set; } + public virtual Flower Flower { get; set; } = new(); + public virtual Shop Shop { get; set; } = new(); + } +} diff --git a/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj b/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj index ca6fa62..49d216b 100644 --- a/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj +++ b/FlowerShop/FlowerShopFileImplement/FlowerShopFileImplement.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable diff --git a/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj b/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj index ca6fa62..49d216b 100644 --- a/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj +++ b/FlowerShop/FlowerShopListImplement/FlowerShopListImplement.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable